icybee / module-pages
管理 Icybee 页面
Requires
- php: >=5.5
- icanboogie/bind-render: ^0.5
- icanboogie/module-installer: ^1.2
- icybee/module-nodes: ^3.0
Requires (Dev)
- brickrouge/brickrouge: ^3.0
- icybee/bluetihi: ^0.0.3
- icybee/patron: ^1.4
- icybee/patron-render-support: ^0.2
README
页面模块(pages
)将“页面”内容类型引入到 CMS Icybee。页面用于创建网站结构、显示内容和视图。该模块提供请求分发器以服务其管理的页面。
蓝图
蓝图是一个简化的数据结构,表示页面之间的关系。它提供子/父关系、父/子关系、索引和树表示。蓝图可以从 查询 创建,也可以从 pages
模型获取。
以下属性是可用的
relations
:子/父关系,键到键。children
:父/子关系,键到键。index
:蓝图节点,按键索引。tree
:蓝图节点,嵌套在树中。model
:与蓝图关联的模型。
从查询中获取蓝图
以下示例演示了如何从 查询 实例中获取蓝图。仅需要 nid
和 parent_id
属性来构建蓝图,但您可能需要更多属性才能使其有用。在示例中,蓝图通过添加 slug
和 pattern
属性创建。
<?php $query = $app->models['pages'] ->select('nid, parent_id, slug, pattern') ->filter_by_site_id($site_id = 1) ->ordered; $blueprint = Blueprint::from($query);
从模型中获取蓝图
可以从 pages
模型中获取蓝图。此蓝图通常用于计算导航或解析路由。它使用额外的属性 is_online
、is_navigation_excluded
和 pattern
创建。
注意:此蓝图是缓存的,即两次以相同参数调用 blueprint()
方法将返回相同的实例。如果您需要修改蓝图本身,建议使用克隆。
<?php $blueprint = $app->models['pages']->blueprint($site_id = 1);
获取蓝图的一个子集
可以从蓝图创建子集,这在您希望处理特定分支或仅处理深度不超过 2 的节点或仅处理在线节点时很有趣。
以下示例演示了如何获取仅具有特定分支的蓝图子集
<?php $subset = $app->models['pages']->blueprint($site_id = 1)->subset(123);
以下示例演示了如何获取具有最大深度为 2 的节点的蓝图子集
<?php $subset = $app->models['pages']->blueprint($site_id = 1)->subset(null, 2);
以下示例演示了如何使用闭包获取仅包含在线节点的蓝图子集
<?php use Icybee\Modules\Pages\BlueprintNode; $subset = $app->models['pages'] ->blueprint($site_id = 1) ->subset(null, null, function(BlueprintNode $node) { return !$node->is_online; }); /* or ->subset(function(BlueprintNode $node) { return !$node->is_online; }); */
填充蓝图
一旦您获取了蓝图,您可能希望用实际记录填充它。使用 populate()
方法通过加载关联的记录来填充蓝图,并使用这些记录更新蓝图节点。无需担心性能,记录通过模型的 find()
方法以单次查询获取,并受益于其缓存机制。
<?php $blueprint->populate(); foreach ($blueprint as $node) { var_dump($node->record); } # or foreach ($blueprint->populate() as $record) { var_dump($record); }
获取有序节点或记录的数组
通过只读属性 ordered_nodes
和 ordered_records
,您可以获取节点或记录的数组。它们根据其权重和关系排序。
<?php $blueprint->ordered_nodes; // an array of BlueprintNodes instances $blueprint->ordered_records; // an array of Page instances
遍历蓝图
蓝图中的 index
包含其所有节点在一个扁平数组中。顺序不重要。
以下示例演示了如何使用蓝图索引遍历蓝图
<?php foreach ($blueprint->index as $node); # or foreach ($blueprint as $node);
导航元素
NavigationElement 类使得从蓝图渲染导航元素变得非常容易。
<?php use Icybee\Modules\Pages\NavigationElement; echo new NavigationElement($blueprint);
渲染结果如下(为了可读性进行了美化)
<ol class="nav lv1"> <li class="page page-id-1 has-children trail"> <a href="/example1">Example 1</a> <ol class="dropdown-menu lv2"> <li class="page page-id-10 active"><a href="/example1/example-a.html">Example A</a></li> <li class="page page-id-11"><a href="/example1/example-b.html">Example B</a></li> </ol> </li> <li class="page page-id-4"> <a href="/contact.html">Contact</a> </li> </ol>
在导航元素填充子元素之前
在将子元素填充到导航元素之前,会触发类 BeforePopulateEvent 的 Icybee\Modules\Pages\NavigationElement::populate:before
事件。
第三方可以使用此事件来修改蓝图。例如,可以使用子集而不是完整的蓝图。
以下代码演示了如何从导航中丢弃具有 ID "5" 的节点
<?php use Icybee\Modules\Pages\BlueprintNode; use Icybee\Modules\Pages\NavigationElement; $app->events->attach(function(NavigationElement\BeforePopulateEvent $event, NavigationElement $target) { $event->blueprint = $event->blueprint->subset(function(BlueprintNode $node) { return $node->nid == 5; }); });
在导航元素填充子元素之后
在将子元素填充到导航元素之后,会触发类 PopulateEvent 的 Icybee\Modules\Pages\NavigationElement::populate
事件。
第三方可以使用此事件来修改导航的可渲染元素。例如,可以替换链接、类或标题。
以下示例演示了如何修改导航链接的 href
和 target
属性
<?php use Icybee\Modules\Pages\NavigationElement; $app->events->attach(function(NavigationElement\PopulateEvent $event, NavigationElement $target) { foreach ($event->blueprint as $node) { $link = $node->renderables['link']; $link['href'] = '#'; $link['target'] = '_blank'; } });
渲染页面
Page 实例使用 PageRenderer 实例进行渲染。这通常由 PageController 处理,但有时你可能需要自己处理,例如渲染你自行创建的 Page 实例,而不需要分发请求。
在渲染前后会触发事件,允许第三方修改渲染过程。
<?php use Icybee\Modules\Pages\Page; use Icybee\Modules\Pages\PageRenderer; $page = Page::form([ 'title' => "My page", 'body' => "My body" ]); $renderer = new PageRenderer; $html = $renderer($page);
该模块还提供了一个默认渲染器,用于将 Page 实例渲染为 HTML 字符串,无论是使用 render()
原型方法还是 __toString()
。
<?php $html = $page->render(); $html = (string) $page;
你可以覆盖 render()
方法来使用自己的渲染器
<?php use ICanBoogie\Prototype; Prototype::from('Icybee\Modules\Pages\Page')['render'] = function(Page $page) { // … return $html; };
在渲染之前
在页面渲染之前,会触发类 BeforeRenderEvent 的 Icybee\Modules\Pages\PageRenderer::render:before
事件。第三方可以使用此事件来修改渲染上下文或文档的资产。
<?php use Icybee\Modules\Pages\PageRenderer; $app->events->attach(function(PageRenderer\BeforeRenderEvent $event, PageRenderer $target) { $event->context['my_variable'] = "My value"; $event->document->css->add('/public/page.css'); $event->document->js->add('/public/page.js'); });
在渲染之后
在页面渲染之后,会触发类 RenderEvent 的 Icybee\Modules\Pages\PageRenderer::render
事件。第三方可以使用此事件来修改生成的 HTML 字符串。
<?php use Icybee\Modules\Pages\PageRenderer; $app->events->attach(function(PageRenderer\RenderEvent $event, PageRenderer $target) { $event->html .= "<!-- My awesome comment -->"; });
使用 inject()
方法在生成的 HTML 中的元素相对位置插入一个 HTML 片段。以下示例演示了如何将 $fragment
变量的内容注入到 BODY
元素的底部。
<?php // … $event->inject($fragment, 'body'); // …
使用 replace()
方法用一个 HTML 片段替换占位符。
<?php // … $event->replace($placeholder, $fragment); // …
原型方法
Icybee\Modules\Sites\Site::lazy_get_home
为 Icybee\Modules\Sites\Site
的实例添加了 home
属性。它返回实例的主页
<?php echo "Home page URL: " . $app->site->home->url;
ICanBoogie\Core::get_page
为 ICanBoogie\Core
的实例添加了 page
属性。它返回当前正在显示的页面。该属性是 $app->request->context->page
的快捷方式。
赞助商标记
以下由模块定义的 Patron 标记:
面包屑:p:breadcrumb
导航:p:navigation
导航:p:navigation:leaf
页面内容:p:page:content
页面语言:p:page:languages
页面区域:p:page:region
页面标题:p:page:title
p:navigation
标记
使用 p:navigation
标记渲染当前页面的导航元素。
<p:navigation css-class-names = string depth = int from-level = int min-children = int parent = int|string|Page> <!-- Content: p:with-param*, template? --> </p:navigation>
可以使用 css-class-names
参数指定导航分支使用的 CSS 类名。默认为 "'-constructor -slug -template'",该值移除了构造函数、slug 和模板名称。导航的最大深度由 depth
参数指定。导航的起始级别由 from-level
参数指定。使用 min-children
参数,如果导航分支不包含足够的直接子元素,则可以丢弃。最后,可以使用 parent
参数指定导航的父元素,它可以指定为 Page 实例、标识符或路径。
<p:navigation /> <p:navigation css-class-names="id slug" /> <p:navigation parent="/blog" depth="1" />
模板使用 NavigationElement 实例作为 thisArg 发布。
<p:navigation> #{@blueprint.dump()=} <ul class="nav"> <p:foreach in="@blueprint.tree"> <li class="#{css_class}"><a href="#{@url}">#{@label}</a></li> </p> </ul> </p:navigation>
p:navigation:leaf
标记
从当前页面渲染导航叶子。
<p:navigation:leaf css-class-name = string depth = int> <!-- Content: p:with-param*, template? --> </p:navigation:leaf>
css-class-name
指定用于生成标题和内容节点的修饰符。默认为 "active trail id"。depth
是分支的最大深度。默认为 2。
模板使用 NavigationBranchElement 实例作为 thisArg 发布。
<p:navigation:leaf /> <!-- or --> <p:navigation:leaf> <div class="nav-branch"> #{@rendered_header=} #{@rendered_content=} </div> </p>
要求
该软件包需要 PHP 5.5 或更高版本。
安装
推荐通过 Composer 安装此软件包。
$ composer require icybee/module-pages
克隆仓库
该软件包在 GitHub 上可用,其仓库可以使用以下命令行克隆
$ git clone https://github.com/Icybee/module-pages.git pages
测试
使用 make test
命令运行测试套件。自动安装 Composer 以及运行套件所需的所有依赖项。可以使用 make clean
命令清理软件包目录。
该软件包由 Travis CI 持续测试。
文档
可以使用 make doc
命令生成软件包及其依赖项的文档。文档使用 ApiGen 在 docs
目录中生成。可以使用 make clean
命令清理软件包目录。
许可
此软件包根据新BSD许可协议授权 - 请参阅 LICENSE 文件获取详细信息。