Wednesday, March 12, 2014

Theme and asset managing for laravel 4

Theme management for Laravel version 4, it is the easiest way to organize your skins, layouts and assets to your laravel 4 website.


Right now Theme supports PHP, Blade, and Twig.


Create theme with artisan CLI


The first time you have to create theme “default” structure, using the artisan command:


php artisan theme:create default

If you change the facade name you can add an option –facade=”Alias”.


To remove an existing theme, use the command:


php artisan theme:destroy default

the type can be php, blade and twig.


Create from the applicaton without CLI.


Artisan::call('theme:create', array('name' => 'foo', '--type' => 'blade'));

 


Configuration


After the config is published, you will see the config file in “app/config/packages/teepluss/theme” location , but all the configuration can be replaced by a config file inside a theme.


Theme config location: /public/themes/[theme]/config.php


The config is convenient for setting up basic CSS/JS, partial composer, breadcrumb template and also metas.


Example:


'events' => array(

// Before event inherit from package config and the theme that call before,
// you can use this event to set meta, breadcrumb template or anything
// you want inheriting.
'before' => function($theme)

// You can remove this line anytime.
$theme->setTitle('Copyright © 2013 - Laravel.in.th');

// Breadcrumb template.
// $theme->breadcrumb()->setTemplate('
// <ul>
// @foreach ($crumbs as $i => $crumb)
// @if ($i != (count($crumbs) - 1))
// <li><a href=" $crumb["url"] "> $crumb["label"] </a><span>/</span></li>
// @else
// <li> $crumb["label"] </li>
// @endif
// @endforeach
// </ul>
// ');
,

// Listen on event before render a theme,
// this event should call to assign some assets,
// breadcrumb template.
'beforeRenderTheme' => function($theme)

// You may use this event to set up your assets.
// $theme->asset()->usePath()->add('core', 'core.js');
// $theme->asset()->add('jquery', 'vendor/jquery/jquery.min.js');
// $theme->asset()->add('jquery-ui', 'vendor/jqueryui/jquery-ui.min.js', array('jquery'));

// $theme->partialComposer('header', function($view)
//
// $view->with('auth', Auth::user());
// );
,

// Listen on event before render a layout,
// this should call to assign style, script for a layout.
'beforeRenderLayout' => array(

'default' => function($theme)

// $theme->asset()->usePath()->add('ipad', 'css/layouts/ipad.css');


)

)

 


Basic usage


class HomeController extends BaseController 

public function getIndex()

$theme = Theme::uses('default')->layout('mobile');

$view = array(
'name' => 'Teepluss'
);

// home.index will look up the path 'app/views/home/index.php'
return $theme->of('home.index', $view)->render();

// Specific status code with render.
// return $theme->of('home.index', $view)->render(200);

// home.index will look up the path 'app/views/mobile/home/index.php'
$theme->ofWithLayout('home.index', $view)->render();

// home.index will look up the path 'public/themes/default/views/home/index.php'
// return $theme->scope('home.index', $view)->render();

// home.index will look up the path 'public/themes/default/views/mobile/home/index.php'
$theme->scopeWithLayout('home.index', $view)->render();

// Looking for a custom path.
// return $theme->load('app.somewhere.viewfile', $view)->render();

// Working with cookie
// $cookie = Cookie::make('name', 'Tee');
// return $theme->of('home.index', $view)->withCookie($cookie)->render();



 


Get only content “$theme->of(‘home.index’)->content();”.


Searching from both theme’s view and application’s view.


$theme = Theme::uses('default')->layout('default');

return $theme->watch('home.index')->render();

 


To check whether your theme exists.


// Returns boolean.
Theme::exists('themename');

 


To find the location of a view.


$which = $theme->scope('home.index')->location();

echo $which; // themer::views.home.index

$which = $theme->scope('home.index')->location(true);

echo $which; // ./app/public/themes/name/views/home/index.blade.php

 


Compiler


This Theme now supports PHP, Blade and Twig. To use Blade or Twig template you just create a file with extension


[file].blade.php or [file].twig.php

 


Render from string.


// Blade template.
return $theme->string('<h1> $name </h1>', array('name' => 'Teepluss'), 'blade')->render();

// Twig Template
return $theme->string('<h1> name </h1>', array('name' => 'Teepluss'), 'twig')->render();

 


 


Compile string


// Blade compile.
$template = '<h1>Name: $name </h1><p> Theme::widget("WidgetIntro", array("userId" => 9999, "title" => "Demo Widget"))->render() </p>';

echo Theme::blader($template, array('name' => 'Teepluss'));

// Twig compile.
$template = '<h1>Name: name </h1><p> Theme.widget("WidgetIntro", "userId" : 9999, "title" : "Demo Widget").render() </p>';

echo Theme::twigy($template, array('name' => 'Teepluss'));

 


Symlink from another view


This is a nice feature when you have multiple files that have the same name, but need to be set as a separate one.


// Theme A : /public/themes/a/views/welcome.blade.php

// Theme B : /public/themes/b/views/welcome.blade.php

// File welcome.blade.php at Theme B is the same as Theme A, so you can do link below:

// ................

// Location: public/themes/b/views/welcome.blade.php
Theme::symlink('a');

// That's it!

 


Basic usage of assets


Add Theme assets in your route.


// path: public/css/style.css
$theme->asset()->add('core-style', 'css/style.css');

// path: public/js/script.css
$theme->asset()->container('footer')->add('core-script', 'js/script.js');

// path: public/themes/[current theme]/assets/css/custom.css
// This case has dependency with "core-style".
$theme->asset()->usePath()->add('custom', 'css/custom.css', array('core-style'));

// path: public/themes/[current theme]/assets/js/custom.js
// This case has dependency with "core-script".
$theme->asset()->container('footer')->usePath()->add('custom', 'js/custom.js', array('core-script'));

You can force use theme to look up existing theme by passing parameter to method: $theme->asset()->usePath(‘default’)


Writing in-line style or script.


// Dependency with.
$dependencies = array();

// Writing an in-line script.
$theme->asset()->writeScript('inline-script', '
$(function()
console.log("Running");
)
', $dependencies);

// Writing an in-line style.
$theme->asset()->writeStyle('inline-style', '
h1 font-size: 0.9em;
', $dependencies);

// Writing an in-line script, style without tag wrapper.
$theme->asset()->writeContent('custom-inline-script', '
<script>
$(function()
console.log("Running");
);
</script>
', $dependencies);

 


Render styles and scripts in your layout.


// Without container
echo Theme::asset()->styles();

// With "footer" container
echo Theme::asset()->container('footer')->scripts();

 


Direct path to theme asset.


echo Theme::asset()->url('img/image.png');

 


Preparing group of assets.


Some assets you  dont need to add on a page right now, but you still need them sometimes, so “cook” and “serve” is your magic.


Cook your assets.


Theme::asset()->cook('backbone', function($asset)

$asset->add('backbone', '//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js');
$asset->add('underscorejs', '//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js');
);

 


You can prepare on a global in package config.


// Location: app/config/packages/teepluss/theme/config.php
....
'events' => array(

....

// This event will fire as a global you can add any assets you want here.
'asset' => function($asset)

// Preparing asset you need to serve after.
$asset->cook('backbone', function($asset)

$asset->add('backbone', '//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js');
$asset->add('underscorejs', '//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js');
);


)
....

 


Serve theme when you need.


// At the controller.
Theme::asset()->serve('backbone');

 


Then you can get output.


...
<head>
<?php echo Theme::asset()->scripts(); ?>
<?php echo Theme::asset()->styles(); ?>
<?php echo Theme::asset()->container('YOUR_CONTAINER')->scripts(); ?>
<?php echo Theme::asset()->container('YOUR_CONTAINER')->styles(); ?>
</head>
...

 


Asset compression


Theme asset has the feature to compress assets by using queue.


// To queue asset outside theme path.
$theme->asset()->queue('queue-name')->add('one', 'js/one.js');
$theme->asset()->queue('queue-name')->add('two', 'js/two.js');

// To queue asset inside theme path.
$theme->asset()->queue('queue-name')->usePath()->add('xone', 'js/one.js');
$theme->asset()->queue('queue-name')->usePath()->add('xtwo', 'js/two.js');

// You can group all assets in a one queue also.
$theme->asset()->queue('queue-name', function($asset)

$theme->asset()->queue('queue-name')->add('one', 'js/one.js');
$theme->asset()->queue('queue-name')->usePath()->add('xtwo', 'js/two.js');
);

 


To render compressed assets inside view.


echo Theme::asset()->queue('queue-name')->scripts(array('defer' => 'defer'));
echo Theme::asset()->queue('queue-name')->styles(array('async' => 'async'));

 


To force compress.


$theme->asset()->queue('queue-name')->compress();

 


When you need best performance on production, you can stop compress using “capture”.


echo Theme::asset()->queue('queue-name')->capture()->scripts();
echo Theme::asset()->queue('queue-name')->capture()->styles();

// Trick !

echo Theme::asset()->queue('queue-name')->capture(App::environmenet() == 'production')->scripts();

// This will stop any process of compression.

 


If you have already published the config before this feature was available, you need to re-publish the config.


Partials


Render a partial in your layouts or views.


// This will look up to "public/themes/[theme]/partials/header.php"
echo Theme::partial('header', array('title' => 'Header'));

 


Partial composer.


$theme->partialComposer('header', function($view)

$view->with('key', 'value');
);

 


Working with regions.


Theme has magic methods to set, prepend and append anything.


$theme->setTitle('Your title');

$theme->appendTitle('Your appended title');

$theme->prependTitle('Hello: ....');

$theme->setAnything('anything');

$theme->setFoo('foo');

// or

$theme->set('foo', 'foo');

 


Render in your layout or view.


Theme::getAnything();

Theme::getFoo();

// or use place.

Theme::place('anything');

Theme::place('foo', 'default-value-if-it-does-not-exist');

// or

Theme::get('foo');

 


Check if the place exists or not.


<?php if (Theme::has('title')) : ?>
<?php echo Theme::place('title'); ?>
<?php endif; ?>

// or

<?php if (Theme::hasTitle()) : ?>
<?php echo Theme::getTitle(); ?>
<?php endif; ?>

 


Get argument assigned to content in layout or region.


Theme::getContentArguments();

// or

Theme::getContentArgument('name');

// To check if it exists

Theme::hasContentArgument('name');

 


Theme::place(‘content’) is a reserve region to render sub-view.


Preparing data to view


Sometimes you don’t need to execute heavy processing, so you can prepare and use when you need it.


$theme->bind('something', function()

return 'This is bound parameter.';
);

 


Using bound data on view.


echo Theme::bind('something');

 


Breadcrumb


In order to use breadcrumbs, follow the instruction below:


$theme->breadcrumb()->add('label', 'http://...')->add('label2', 'http:...');

// or

$theme->breadcrumb()->add(array(
array(
'label' => 'label1',
'url' => 'http://...'
),
array(
'label' => 'label2',
'url' => 'http://...'
)
));

 


To render breadcrumbs.


echo $theme->breadcrumb()->render();

// or

echo Theme::breadcrumb()->render();

 


You can setup breadcrumbs template anywhere you want by using a blade template.


$theme->breadcrumb()->setTemplate('
<ul>
@foreach ($crumbs as $i => $crumb)
@if ($i != (count($crumbs) - 1))
<li><a href=" $crumb["url"] "> $crumb["label"] </a><span>/</span></li>
@else
<li> $crumb["label"] </li>
@endif
@endforeach
</ul>
');

 


Theme Widgets Design Structure


Theme has many useful features to use in your site called “widget” that can be anything.


Creating a widget


You can create a widget class using artisan command:


Creating as a global.


php artisan theme:widget demo --global --type=blade --case=snake

 


Widget tpl is located in /app/views/widgets/widget-tpl.extension


Creating a specific theme name.


php artisan theme:widget demo default --type=blade

 


Widget tpl is located in /public/themes/[theme]/widgets/widget-tpl.extension


The file name can be demo.php, demo.blade.php or demo.twig.php


Now you will see a widget class at /app/widgets/WidgetDemo.php


<h1>User Id: $label </h1>

 


Calling your widget in layout or view


echo Theme::widget('demo', array('label' => 'Demo Widget'))->render();

 


Using theme global


class BaseController extends Controller 

/**
* Theme instance.
*
* @var \Teepluss\Theme\Theme
*/
protected $theme;

/**
* Construct
*
* @return void
*/
public function __construct()

// Using theme as a global.
$this->theme = Theme::uses('default')->layout('ipad');



 


To override theme or layout.


public function getIndex()

$this->theme->uses('newone');

// or just override layout
$this->theme->layout('desktop');

$this->theme->of('somewhere.index')->render();

 



Theme and asset managing for laravel 4

No comments:

Post a Comment