heimrichhannot/contao-syndication-type-bundle

此扩展为contao提供可扩展的聚合框架。

0.5.9 2024-03-28 13:08 UTC

README

Latest Stable Version Total Downloads

此扩展为contao提供可扩展的聚合框架。聚合可以轻松添加到您的自己的扩展/模块/元素中。已提供一些支持捆绑/实体(请参阅功能部分)。

功能

  • 内置支持以下聚合:
  • 捆绑聚合类型
    • 分享:facebook,邮件,邮件反馈,twitter,whatsapp,xing,linkedin
    • 导出:ical,打印
  • 可扩展和可自定义的聚合框架
  • 生成的链接和链接列表实现了 PSR-13 LinkInterfaceLinkProviderInterface

用法

要求

  • php ^7.2
  • contao ^4.4
  • ical (.ics) 导出:eluceo/ical (^0.16)
  • PDF导出:heimrichhannot/contao-pdf-creator-bundle

安装

  1. 使用composer或contao manager安装

    composer require heimrichhannot/contao-syndication-type-bundle
    
  2. 更新数据库

文章聚合

您可以用此扩展的聚合替换contao文章聚合。

  1. huh_syndication_type.enable_article_syndication 设置为true(在您的项目config.yml中)
  2. 清除您的缓存并更新数据库
  3. 您将在文章配置中找到新的聚合配置

内容元素聚合

您可以将聚合作为内容元素添加到每篇文章中。

  1. huh_syndication_type.enable_content_syndication 设置为true(在您的项目config.yml中)
  2. 清除您的缓存并更新数据库
  3. 您将在内容元素类型选择中找到新的聚合类型

Reader Bundle

  1. 创建一个新的聚合配置元素
  2. 选择聚合
  3. 在您的模板中输出模板变量(使用raw过滤器)

打印内容

要打印内容,您有两种选择:打印整个页面(简单的window.print()链接)或使用自定义模板进行打印。打印模板是用twig编写的,文件名必须以syndication_type_print_开头,例如syndication_type_print_default.html.twig。您可以扩展默认模板或创建一个完整的自定义模板。

在创建打印模板时,您可能希望在不打开打印弹出窗口的情况下查看预览。要获取一个,只需将synPrintDebug参数追加到打印URL中。

开发者

自定义链接渲染

如果您需要对链接渲染的输出有更多控制,您有多种选择

覆盖或更改默认模板

您可以覆盖以下模板(使用contao模板继承与twig模板,感谢Twig Support Bundle

  • syndication_provider_default.html.twig
  • syndication_link_default.html.twig

还可以创建自定义版本,例如 syndication_provider_acme.html.twig。要使用自定义链接模板,您可以使用 BeforeRenderSyndicationLinks 事件,在调用 SyndicationLinkRenderer 方法时传递选项,或者装饰 SyndicationLinkRenderer 服务。通过在调用 SyndicationLinkRenderer 方法时传递选项或装饰 SyndicationLinkRenderer 服务,可以更改提供者模板。

使用 BeforeRenderSyndicationLinks 事件

您可以通过 BeforeRenderSyndicationLinks 自定义渲染的选项和链接。

示例(Contao 4.9+)

namespace Acme\ExampleBundle\EventListener;

use HeimrichHannot\SyndicationTypeBundle\Event\BeforeRenderSyndicationLinksEvent;
use Terminal42\ServiceAnnotationBundle\Annotation\ServiceTag;

/**
 * @ServiceTag("kernel.event_listener", event="HeimrichHannot\SyndicationTypeBundle\Event\BeforeRenderSyndicationLinksEvent")
 */
class SyndicationBeforeRenderSyndicationLinksEventListener
{
    public function __invoke(BeforeRenderSyndicationLinksEvent $event): void
    {
        $options = $event->getLinkRenderOptions();
        $options['template'] = 'syndication_link_acme';
        $event->setLinkRenderOptions($options);
    }
}

装饰 SyndicationLinkRenderer 服务

您可以通过装饰 SyndicationLinkRenderer 服务来自定义所有选项。如果您不熟悉这个,它听起来可能很复杂,但 symfony 使其变得简单,以下是一个工作示例(只需更改命名空间和类名)

# services.yml
services:
  App\Syndication\DecoratedLinkRenderer:
    decorates: HeimrichHannot\SyndicationTypeBundle\SyndicationLink\SyndicationLinkRenderer
    arguments: ['@App\Syndication\DecoratedLinkRenderer.inner']
use HeimrichHannot\SyndicationTypeBundle\SyndicationLink\SyndicationLinkRenderer;

class DecoratedLinkRenderer extends SyndicationLinkRenderer
{
    protected SyndicationLinkRenderer $inner;

    public function __construct(SyndicationLinkRenderer $inner)
    {
        $this->inner = $inner;
    }

    public function renderProvider(SyndicationLinkProvider $provider, array $options = []): string
    {
        // Tell the renderProvider method to call the customized render method
        return $this->inner->renderProvider($provider, array_merge($options, [
            'render_callback' => [$this, 'render']
        ]));
    }

    public function render(SyndicationLink $link, array $options = []): string
    {
        // add or customize link attributes
        $options['attributes']['class'] = trim(($options['attributes']['class']  ?? '').' btn btn-primary');
        // don't output template dev comments
        $options['disable_dev_comments'] = true;
        // a custom template (pass only the name)
        $options['template'] = 'a_really_custom_link_template';
        // override the link content
        $options['content'] = "Click THIS link!";
       
        return $this->inner->render($link, $options);
    }
}

将聚合功能添加到您的包中

聚合包旨在可重用。您可以轻松地将它添加到您的代码中。

  1. 将所有需要的字段添加到您的 dca 中

    • 我们建议创建一个监听 loadDataContainer 钩子
    • 使用 SyndicationTypeDcaProvider::prepareDca($table) 添加字段和配置
    • 使用 SyndicationTypeDcaProvider::getPalette() 生成调色板并将其放置在适当的位置。您可以通过传递布尔参数来获取按图例分开的调色板或不分开的调色板。
    use HeimrichHannot\SyndicationTypeBundle\Dca\SyndicationTypeDcaProvider;
    
    function prepareTable(string $table, SyndicationTypeDcaProvider $syndicationTypeDcaProvider)
      {
          $dca = &$GLOBALS['TL_DCA']['tl_article'];
          $dca['palettes']['default'] = str_replace(
            'printable', 
            $syndicationTypeDcaProvider->getPalette(false), 
            $dca['palettes']['default']
          );
          $syndicationTypeDcaProvider->prepareDca($table);
      }
  2. 在控制器/模块/监听器/... 中生成聚合链接

    • 创建一个 SyndicationContext 实例
    • 使用 SyndicationLinkProviderGenerator::generateFromContext() 生成聚合链接(将返回一个 SyndicationLinkProvider 实例,它是一个 SyndicationLink 实例的集合)
    • 使用 SyndicationLinkRenderer::renderProvider() 渲染聚合链接(将返回渲染后的链接作为字符串。您也可以使用/创建一个自定义链接渲染器)

    为了便于实现,您可以通过 SyndicationManager 访问所有这些服务。

    use HeimrichHannot\SyndicationTypeBundle\Manager\SyndicationManager;
    
    class ExampleController {
    
        private SyndicationManager               $syndicationManager;
    
        public function addSyndication(string $title, string $content, array $itemData, ExampleModel $config): string
        {
            // $title: A title for the syndication
            // $content: What should be shared. Can be a teaser text or a rendered template.
            // $itemData: The data of the entity to share
            // $config: The configuration. Typical the model data (row) of the configuration. Maybe the same as item data.
            $context = $this->syndicationManager->createContext($title, $content, $itemData, $config->row());
            
            // See next paragraph
            $this->doExport($context);
            
            $provider = $this->syndicationManager->getLinkProviderGenerator()->generateFromContext($context);
            $rendererContext = $this->syndicationManager->createLinkRendererContextFromModel();
            
            return $this->syndicationManager->getLinkRenderer()->renderProvider($provider, $rendererContext);
        }
    
    }
  3. 添加导出支持。

    • 这应该在您的导出内容完全配置和完全渲染(或可以完全渲染)的地方完成。在大多数情况下,这可以在生成聚合链接的地方完成,但也可能需要在稍后的某个时间点完成。
    • 创建一个 SyndicationContext 实例
  • 运行 ExportSyndicationHandler::exportByContext()

    use HeimrichHannot\SyndicationTypeBundle\Manager\SyndicationManager;
    use HeimrichHannot\SyndicationTypeBundle\SyndicationContext\SyndicationContext;
        
    class ExampleController {
    
        private SyndicationManager               $syndicationManager;
        
        private function doExport(SyndicationContext $syndicationContext): void
        {
            $this->syndicationManager->getExportSyndicationHandler()->exportByContext($context);
        }
        
    }

添加自定义聚合类型

  1. 创建一个 SyndicationType 类
    • 该类必须实现 SyndicationTypeInterface(或 ExportSyndicationTypeInterface
    • 您可以(并且我们推荐)扩展 AbstractSyndicationTypeAbstractExportSyndicationType(对于执行导出操作如 pdf、打印或 ical 的聚合类型),这些抽象类已经实现了它们相应的接口
  2. 实现抽象方法
    • getType() - 返回聚合类型的别名
    • generate() - 生成聚合链接。传递一个 SyndicationContext 实例,必须返回一个 SyndicationLink 实例。我们建议使用 SyndicationLinkFactory 创建 SyndicationLink 实例。
  3. 可选:如果您的 SyndicationType 扩展了其中一个抽象类,您可以重写以下方法
    • getCategory() - 自定义聚合类别。在 AbstractSyndicationType 中预定义了两个类别作为常量:shareexport,但可以使用自定义类别
    • getPalette() - 如果您的聚合类型依赖于额外的配置,您可以在此处设置聚合类型的调色板
  4. 可选:如果您的 SyndicationType 扩展了其中一个抽象类,您可以使用以下辅助方法
    • getValueByFieldOption() - 从上下文中返回配置值(简写,这样您就不必进行所有数组验证)
    • appendGetParameterToUrl() - 将 get 参数附加到 url 上的实用工具。对于创建导出链接很有用
  5. 使用 huh.syndication_type.type 服务标签将服务类型类注册为服务
  6. AddSyndicationTypeFieldsEventAddSyndicationTypePaletteSelectorsEventAddSyndicationTypeSubpalettesEvent 创建事件订阅者,以添加自定义 dca 字段和子面板

配置参考

# Default configuration for extension with alias: "huh_syndication_type"
huh_syndication_type:

    # Enable this option to replace the default contao article syndication with syndication type bundle article syndication.
    enable_article_syndication: false
    enable_content_syndication: false