官方教程:https://packagist.org/packages/teepluss/theme
主题将帮助您轻松地在Laravel项目中组织主题,并在单个目录中维护主题的相关资产,布局和部分。
在应用主目录的composer.json里加入: “teepluss/theme”: “^2.0”
"require": {
"php": ">=5.5.9",
"laravel/framework": "5.1.*",
"barryvdh/laravel-ide-helper": "^2.4",
"doctrine/dbal": " ~2.3",
"teepluss/theme": "^2.0"
},
- 在项目根目录输入以下命令
composer require teepluss/theme
- 安装主题后,您需要向应用程序注册服务提供商。打开config/app.php并找到providers钥匙。
'providers' => [
Teepluss\Theme\ThemeServiceProvider::class,
]
- 执行
composer install
- 主题还附带了一个外观,它提供了创建集合的静态语法。您可以在文件的aliases密钥中注册外观config/app.php。
'aliases' => [
'Theme' => Teepluss\Theme\Facades\Theme::class,
]
- 使用artisan CLI发布配置。
php artisan vendor:publish --provider="Teepluss\Theme\ThemeServiceProvider"
- 发布 config/themes.php 配置文件, 配置文件在config/theme.php
php artisan vendor:publish --provider=Hongyukeji\\LaravelTheme\\ThemeServiceProvider
- 使用:
// 1. 在 config/themes.php 中 添加 templates, 如:
'frontend' => [
'path_prefix' => 'resources/views/frontend/',
'template' => 'default',
'template_default' => 'default',
],
// 2. 在控制器中使用:
public function index()
{
return view('frontend::index.index');
}
用法
主题有很多功能可以帮助您开始使用Laravel
- 使用artisan CLI创建主题
第一次使用artisan命令创建主题“默认”结构时:
php artisan theme:create default
如果更改外观名称,则可以添加选项–facade =“Alias”。
要删除现有主题,请使用以下命令:
php artisan theme:destroy default
无需CLI即可从应用程序创建。
Artisan :: call(' theme:create ',[ ' name ' => ' foo ',' - type ' => ' blade ' ]);
- 组态
发布配置后,您将在“config / theme”中看到配置文件,但所有配置都可以由主题内的配置文件替换。
主题配置位置:/public/themes/[theme]/config.php
配置方便设置基本的CSS/JS, partial composer, breadcrumb template以及元数据(metas)。
例:
//config/theme.php
'events' => array(
// 事件之前从包配置和之前调用的主题中继承,
//您可以使用此事件来设置meta、breadcrumb模板或任何你想要继承的东西
'before' => function($theme)
{
// You can remove this line anytime.
$theme->setTitle('Copyright © 2013 - Laravel.in.th');
// Breadcrumb template.
// $theme->breadcrumb()->setTemplate('
// <ul class="breadcrumb">
// @foreach ($crumbs as $i => $crumb)
// @if ($i != (count($crumbs) - 1))
// <li><a href="{{ $crumb["url"] }}">{{ $crumb["label"] }}</a><span class="divider">/</span></li>
// @else
// <li class="active">{{ $crumb["label"] }}</li>
// @endif
// @endforeach
// </ul>
// ');
},
// 在渲染主题之前先监听听事件,
// 此事件会被调用以分配一些资产 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());
// });
},
// 在渲染布局前监听事件,
//这会被调用未layout分配style,script
'beforeRenderLayout' => array(
'default' => function($theme)
{
// $theme->asset()->usePath()->add('ipad', 'css/layouts/ipad.css');
}
)
)
- 基本用法
amespace App\Http\Controllers;
use Theme;
class HomeController extends Controller {
public function getIndex()
{
//使用public/themes/default/views/layouts/manage.blade.php布局
$theme = Theme::uses('default')->layout('mobile');
$view = array(
'name' => 'Teepluss'
);
// home.index 将查找路径 'resources/views/home/index.php'
return $theme->of('home.index', $view)->render();
// 用来渲染的状态码
return $theme->of('home.index', $view)->render(200);
// home.index 将查找路径 'resources/views/mobile/home/index.php'
return $theme->ofWithLayout('home.index', $view)->render();
// home.index 将查找路径 'public/themes/default/views/home/index.php'
// home.index的html内容将被加载到Theme里, view中可以这样调用 {!! Theme::partial('managesetting') !!}
return $theme->scope('home.index', $view)->render();
// home.index 将查找路径 'public/themes/default/views/mobile/home/index.php'
return $theme->scopeWithLayout('home.index', $view)->render();
// 寻找自定义路径.
return $theme->load('app.somewhere.viewfile', $view)->render();
// 使用cookie
$cookie = Cookie::make('name', 'Tee');
return $theme->of('home.index', $view)->withCookie($cookie)->render();
}
}
$theme->of('home.index')->content(); //只获取内容
从主题视图和应用程序视图中查找。
$theme = Theme::uses('default')->layout('default');
return $theme->watch('home.index')->render();
检查主题是否存在
// Returns boolean.
Theme::exists('themename');
查找视图的位置。
$which = $theme->scope('home.index')->location();
echo $which; // themer::views.home.index
$which = $theme->scope('home.index')->location(true);
echo $which; // ./public/themes/name/views/home/index.blade.php
编辑器
theme现在支持PHP、Blade和Twig。要使用Blade或Twig模板,只需创建一个扩展名文件
[file].blade.php or [file].twig.php
从字符串渲染
// 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();
编译字符串
/ 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'));
来自另一个视图的符号链接
当您有多个具有相同名称的文件但需要作为单独的文件定位时,这是一个很好的功能。
// 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!
- assets的基本用法
在路由添加assets
// 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'));
书写内联式或脚本。
// 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);
在 layout 中渲染 styles 和scripts
Without container
echo Theme::asset()->styles();
// With "footer" container
echo Theme::asset()->container('footer')->scripts();
给 theme 分配直接的路径资源
echo Theme::asset()->url('img/image.png');
准备assets组
有些资源你现在不想添加到页面上,但是有时候你仍然需要它们,所以“cook”和“serve”是你的魔法。
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');
});
您可以在全局包内配置上进行准备。
// Location: config/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
/ At the controller.
Theme::asset()->serve('backbone');
然后就可以在视图输出
...
<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>
...
Partials(局部模板)
在你的layouts或者views渲染Partials
/ This will look up to "public/themes/[theme]/partials/header.php"
echo Theme::partial('header', array('title' => 'Header'));
// Partial with current layout specific.
//这将找到并使用当前布局(layout)下的header.php "public/themes/[theme]/partials/[CURRENT_LAYOUT]/header.php"
echo Theme::partialWithLayout('header', array('title' => 'Header'));
从主题部分和应用程序部分中查找。
echo Theme::watchPartial('header', array('title' => 'Header'));
Partial composer.
$theme->partialComposer('header', function($view)
{
$view->with('key', 'value');
});
// Working with partialWithLayout.
$theme->partialComposer('header', function($view)
{
$view->with('key', 'value');
},
在局部设置
Theme 有 magic 方法 来设置,前置和附加任何东西。
$theme->setTitle('Your title');
$theme->appendTitle('Your appended title');
$theme->prependTitle('Hello: ....');
$theme->setAnything('anything');
$theme->setFoo('foo');
// or
$theme->set('foo', 'foo');
渲染你的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');
检查这个地方是否存在。
<?php if (Theme::has('title')) : ?>
<?php echo Theme::place('title'); ?>
<?php endif; ?>
// or
<?php if (Theme::hasTitle()) : ?>
<?php echo Theme::getTitle(); ?>
<?php endif; ?>
获取分配给布局或区域中内容的参数。
Theme::getContentArguments();
// or
Theme::getContentArgument('name');
// To check if it exists
Theme::hasContentArgument('name');
- 为view准备数据
有时您不需要执行繁重的处理,所以您可以在需要时准备并使用它。
$theme->bind('something', function()
{
return 'This is bound parameter.';
});
在视图上使用绑定数据。
echo Theme::bind('something');
- Breadcrumb
要使用Breadcrumb,请遵循以下说明:
$theme->breadcrumb()->add('label', 'http://...')->add('label2', 'http:...');
// or
$theme->breadcrumb()->add(array(
array(
'label' => 'label1',
'url' => 'http://...'
),
array(
'label' => 'label2',
'url' => 'http://...'
)
));
渲染breadcrumbs
echo $theme->breadcrumb()->render();
// or
echo Theme::breadcrumb()->render();
您可以使用blade模板在任何地方设置breadcrumb模板。
$theme->breadcrumb()->setTemplate('
<ul class="breadcrumb">
@foreach ($crumbs as $i => $crumb)
@if ($i != (count($crumbs) - 1))
<li><a href="{{ $crumb["url"] }}">{{ $crumb["label"] }}</a><span class="divider">/</span></li>
@else
<li class="active">{{ $crumb["label"] }}</li>
@endif
@endforeach
</ul>
');
- Widgets Design Structure(小部件设计结构)
主题有许多有用的功能,称为“widget”,可以是任何东西。
创建widget
您可以使用artisan命令创建一个小部件类:
创造一个全局widget。
php artisan theme:widget demo --global --type=blade
Widget tpl 在本地的 “resources/views/widgets/{widget-tpl}.{extension}”
创建特定的主题名称。
php artisan theme:widget demo default --type=blade
Widget tpl is located in “public/themes/[theme]/widgets/{widget-tpl}.{extension}”
文件名可以是demo.php、demo.blade.php或demo.twig.php。
现在,您将在/app/widgets/widgetdemo.php上看到一个widget类。
//app/widgets/widgetdemo.php
<h1>User Id: {{ $label }}</h1>
在布局或视图中调用widget
echo Theme::widget('demo', array('label' => 'Demo Widget'))->render();
使用 全局theme
use Teepluss\Theme\Contracts\Theme;
use App\Http\Controllers\Controller;
class BaseController extends Controller {
/**
* Theme instance.
*
* @var \Teepluss\Theme\Theme
*/
protected $theme;
/**
* Construct
*
* @return void
*/
public function __construct(Theme $theme)
{
// Using theme as a global.
$this->theme = $theme->uses('default')->layout('ipad');
}
}
覆盖主题或布局
public function getIndex()
{
$this->theme->uses('newone');
// or just override layout
$this->theme->layout('desktop');
$this->theme->of('somewhere.index')->render();
}
// 3. 在视图目录新建frontend目录和对应的index(frontend => 终端, default => 主题):
resources/views/frontend
resources/views/frontend/default
resources/views/frontend/default/index
resources/views/frontend/default/index/index.blade.php
- templates 参数说明:
- path_prefix 为每个终端模板目录路径
- template 为使用模板的目录
- template_default 为默认模板目录,即找不到 template 模板对应的目录文件,会自动在该参数定义的目录去查找 助手函数你可能会需要:
- get_template_dir 获取给定目录下的所有目录