roadiz/abstract-blog-theme

为Roadiz主题提供的抽象博客中间件。

2.1.1 2023-09-26 13:52 UTC

README

为Roadiz主题提供的抽象博客中间件。

继承

您的自定义主题入口类必须扩展AbstractBlogThemeApp而不是FrontendController以提供基本方法

use Themes\AbstractBlogTheme\AbstractBlogThemeApp;

class MyThemeApp extends AbstractBlogThemeApp
{
    //…
}

依赖注入

编辑您自己的app/AppKernel.php以注册博客服务

use Themes\AbstractBlogTheme\Services\BlogServiceProvider;

/**
 * {@inheritdoc}
 */
public function register(\Pimple\Container $container)
{
    parent::register($container);
    $container->register(new BlogServiceProvider());
}

您必须在自定义主题中覆盖这些服务

  • blog_theme.post_container_entity
  • blog_theme.post_entity

使用您自己的节点类型类名。

/**
 * @param Container $container
 */
public static function setupDependencyInjection(Container $container)
{
    parent::setupDependencyInjection($container);
    
    $container->extend('blog_theme.post_container_entity', function ($entityClass) {
        return NSBlogPostContainer::class;
    });
    
    $container->extend('blog_theme.post_entity', function ($entityClass) {
        return NSBlogPost::class;
    });
}

添加节点类型

抽象博客主题声明了3个节点类型来创建您的博客网站

  • BlogFeedBlock:在任意页面上创建自动的源预览
  • BlogPost:主要的博客文章实体
  • BlogPostContainer:博客容器,用于托管每个博客文章
bin/roadiz themes:install --data Themes/AbstractBlogTheme/AbstractBlogThemeApp
bin/roadiz generate:nsentities
bin/roadiz orm:schema-tool:update --dump-sql --force

PostContainerControllerTrait

PostContainerControllerTrait将实现您的indexAction,通过处理所有请求数据来提供您的文章、过滤器和可用标签以构建您的模板。

IndexAction将分配

  • posts:根据您的标准找到的NodesSources数组
  • filters:分页信息数组
  • tags:可用的过滤Tag数组
  • currentTagTagarraynull
  • currentTagNamesarray包含当前过滤标签(s)的名称,用于过滤菜单模板。
  • currentRelationSourceNodesSourcesnull包含过滤相关实体
  • currentRelationsSourcesarray包含当前过滤相关实体(s),用于过滤菜单模板。
  • currentRelationsNamesarray包含当前过滤相关实体(s)的名称,用于过滤菜单模板。
  • archives:可用的年份月份的帖子存档
  • currentArchivestring未定义
  • currentArchiveDateTime\DateTime未定义

过滤

您可以使用Request属性或查询参数来过滤您的帖子容器实体

  • tag:使用Roadiz节点的tags字段按标签名称过滤。您可以传递一个标签名称数组以合并它们。
  • archive:按月份和年份或仅按publishedAt字段上的年份过滤,或使用getPublicationField方法定义的年份过滤。
  • related:使用Roadiz节点的bNodes字段按相关节点名称过滤。您可以传递一个节点名称数组以合并它们。

用法

您只需在主题中创建您的PostContainer节点源Controller并实现ConfigurableController,然后使用PostContainerControllerTrait。您将能够覆盖任何方法来配置您的博客列表。

<?php
namespace Themes\MyTheme\Controllers;

use Themes\AbstractBlogTheme\Controllers\ConfigurableController;
use Themes\AbstractBlogTheme\Controllers\PostContainerControllerTrait;
use Themes\MyTheme\MyThemeThemeApp;

class BlogPostContainerController extends MyThemeThemeApp implements ConfigurableController
{
    use PostContainerControllerTrait;
}

多个容器控制器使用

如果您有多个博客文章类型(例如BlogpostPressReview),我们强烈建议在您的主题中使用此Trait之前创建一个Abstract类,这将在您有多个容器控制器类时简化方法覆盖。

<?php
namespace Themes\MyTheme\Controllers;

use Themes\AbstractBlogTheme\Controllers\ConfigurableController;
use Themes\AbstractBlogTheme\Controllers\PostContainerControllerTrait;
use Themes\MyTheme\MyThemeThemeApp;

abstract class AbstractContainerController extends MyThemeThemeApp implements ConfigurableController
{
    use PostContainerControllerTrait;

    // common methods overriding here…
}

然后,简单地在您的多个容器控制器定义中继承您的Abstract

<?php
namespace Themes\MyTheme\Controllers;

class BlogPostContainerController extends AbstractContainerController
{
    // override whatever you want
}

class PressReviewContainerController extends AbstractContainerController
{
    // override whatever you want
}

覆盖PostContainerControllerTrait行为

这些方法可以被覆盖以自定义您的PostContainerControllerTrait行为。

  • getTemplate:默认返回 pages/post-container.html.twig。它将在每个已注册的主题中搜索此模板,并在 @AbstractBlogTheme/pages/post-container.html.twig 上回退。请确保您自己的主题有更高的优先级。
  • getRssTemplate:默认返回 pages/post-container.rss.twig。它将在每个已注册的主题中搜索此模板,并在 @AbstractBlogTheme/pages/post-container.rss.twig 上回退。请确保您自己的主题有更高的优先级。
  • throwExceptionOnEmptyResult:默认返回 true。当找不到帖子时,它会抛出一个 404 错误。
  • getPostEntity:默认返回 $this->get('blog_theme.post_entity') 作为类名字符串。您可以自定义它以列出其他节点。
  • isScopedToCurrentContainer:默认返回 falsePostContainerControllerTrait 将获取所有博客帖子,无论它们在哪里。如果您的 isScopedToCurrentContainer 方法返回 true,则所有博客帖子都只从您的当前容器中获取,这允许您创建多个博客容器。
  • isTagExclusive:默认返回 true,匹配与所有标签相关联的帖子(交集)。如果要匹配与任何标签相关的帖子(并集),请将其重写为 false
  • getPublicationField:默认此方法返回 publishedAt 字段名称。除非字段存在于您的 BlogPost 节点类型中,否则您可以返回任何名称。
  • getDefaultCriteria:默认返回默认帖子查询条件。我们鼓励您重写 getCriteria 以保留默认标签、存档和相关过滤系统。
  • getCriteria:重写默认帖子查询条件,此方法必须返回一个数组。
  • getDefaultOrder:默认此方法返回一个数组
[
    $this->getPublicationField() => 'DESC'
]
  • getResponseTtl:默认此方法返回 5(分钟)。
  • selectPostCounts:默认 false:执行额外查询以获取每个标签的帖子数以在标签菜单中显示帖子计数。
  • prepareListingAssignation:这是执行所有查询和标签解析的关键方法。我们不推荐重写此方法,而是重写其他方法以更改 PostContainer 的行为。
  • getRelatedNodesSourcesQueryBuilder:如果您只想获取一个类型的相关节点源。或进行更精确的过滤。

您可以重写其他方法,只需查看 PostContainerControllerTrait 文件...

PostControllerTrait

PostControllerTrait 将通过处理所有请求数据来实现您的 indexAction,以提供单个帖子及其多种格式。

用法

您需要做的只是创建您的主题中的 Post 节点源 Controller 并实现 ConfigurableController,然后使用 PostControllerTrait

<?php
namespace Themes\MyTheme\Controllers;

use Themes\AbstractBlogTheme\Controllers\ConfigurableController;
use Themes\AbstractBlogTheme\Controllers\PostControllerTrait;
use Themes\MyTheme\MyThemeThemeApp;

class BlogPostController extends MyThemeThemeApp implements ConfigurableController
{
    use PostControllerTrait;
}

覆盖PostControllerTrait行为

这些方法可以重写以自定义 PostControllerTrait 的行为。

  • getJsonLdArticle:默认返回一个将被序列化为 JSON 或 AMP 适配格式的新 JsonLdArticle
  • getTemplate:默认返回 pages/post.html.twig。它将在每个已注册的主题中搜索此模板,并在 @AbstractBlogTheme/pages/post.html.twig 上回退。请确保您自己的主题有更高的优先级。
  • getAmpTemplate:默认返回 pages/post.amp.twig。它将在每个已注册的主题中搜索此模板,并在 @AbstractBlogTheme/pages/post.amp.twig 上回退。请确保您自己的主题有更高的优先级。
  • allowAmpFormat:默认返回 true
  • allowJsonFormat:默认返回 true
  • getResponseTtl:默认此方法返回 5(分钟)。

使用Solr的搜索引擎

<?php
namespace Themes\MyTheme\Controllers;

use Themes\AbstractBlogTheme\Controllers\ConfigurableController;
use Themes\AbstractBlogTheme\Controllers\SearchControllerTrait;
use Themes\MyTheme\MyThemeApp;

class SearchController extends MyThemeApp implements ConfigurableController
{
    use SearchControllerTrait;
}
searchPageLocale:
    path: /{_locale}/search.{_format}/{page}
    defaults:
        _controller: Themes\MyTheme\Controllers\SearchController::searchAction
        _locale: en
        page: 1
        _format: html
    requirements:
        # Use every 2 letter codes (quick and dirty)
        _locale: "en|fr"
        page: "[0-9]+"
        _format: html|json

在您的网站模板中添加您的搜索表单(使用 GET 方法启用用户历史记录)

<form method="get" action="{{ path('searchPageLocale', {
    '_locale': request.locale
}) }}" data-json-action="{{ path('searchPageLocale', {
    '_locale': request.locale,
    '_format': 'json',
}) }}" id="search">
    <input type="search" name="q">
    <button type="submit">{% trans %}search{% endtrans %}</button>
</form>

然后创建 pages/search.html.twig 模板。

覆盖PostControllerTrait行为

  • getTemplate():字符串
  • getAmpTemplate():字符串
  • getJsonLdArticle():JsonLdArticle
  • getResponseTtl():字符串
  • allowAmpFormat():布尔值
  • allowJsonFormat():布尔值

搜索结果模型

对于JSON搜索响应,SearchControllerTrait 使用JMS序列化器与自定义模型来装饰您的节点源及其高亮文本。默认情况下,SearchControllerTrait 实例化一个 Themes\AbstractBlogTheme\Model\SearchResult 对象,该对象将被序列化。如果您想根据节点源数据添加自定义字段,则可以覆盖此模型。

创建一个子类,然后重写 createSearchResultModel 方法

/**
 * @param $searchResult
 *
 * @return SearchResult
 */
protected function createSearchResultModel($searchResult)
{
    return new SearchResult(
        $searchResult['nodeSource'],
        $searchResult['highlighting'],
        $this->get('document.url_generator'),
        $this->get('router'),
        $this->get('translator')
    );
}

您将能够在子 SearchResult 模型中添加新的虚拟属性。

支持AMP移动页面

支持博客文章详情页的 AMP 格式。

  • 禁用 display_debug_panel 设置
  • 在您的博客文章详情页Url后添加 ?amp=1。或者,为了开发模式,添加 ?amp=1#development=1
  • 在您的HTML模板中添加amp link
{% block share_metas %}
    {{ parent() }}
    <link rel="amphtml" href="{{ url(nodeSource, {'amp': 1}) }}">
{% endblock %}

支持RSS源

RSS格式支持博客文章 容器 列表页。

  • 将RSS link 添加到您的HTML模板中
{% block share_metas %}
    {{ parent() }}
    <link rel="alternate" href="{{ url(nodeSource, {
            '_format': 'xml',
            'page': filters.currentPage,
            'tag': currentTag.tagName,
            'archive': currentArchive
        }) }}" title="{{ pageMeta.title }}" type="application/rss+xml">
{% endblock %}

模板

Resources/views/ 文件夹包含用于创建您自己的博客的有用模板。您可以直接在主题中使用它们或复制它们。

默认情况下,您的Roadiz网站将直接使用 AbstractBlogTheme 模板。您可以使用完全相同的路径和名称在继承的主题中覆盖它们。

Twig扩展

函数

  • get_latest_posts($translation, $count = 4)
  • get_latest_posts_for_tag($tag, $translation, $count = 4)
  • get_previous_post($nodeSource, $count = 1, $scopedToParent = false):按 publishedAt 排序获取上一篇文章。
    默认返回单个 NodesSource,如果 count > 1,则返回一个 array
  • get_previous_post_for_tag($nodeSource, $tag, $count = 1, $scopedToParent = false):按 publishedAt 排序并按一个 Tag 过滤获取上一篇文章。
    默认返回单个 NodesSource,如果 count > 1,则返回一个 array
  • get_next_post($nodeSource, $count = 1, $scopedToParent = false):按 publishedAt 排序获取下一篇文章。
    默认返回单个 NodesSource,如果 count > 1,则返回一个数组。
  • get_next_post_for_tag($nodeSource, $tag, $count = 1, $scopedToParent = false):按 publishedAt 排序并按一个 Tag 过滤获取下一篇文章。
    默认返回单个 NodesSource,如果 count > 1,则返回一个 array

过滤器

  • ampifize:删除AMP格式中不受支持的标签,并将 imgiframe 标签转换为它们的 AMP 等效标签。