t3g/symfony-template-bundle

TYPO3 模板包

安装次数: 18,427

依赖: 0

建议者: 0

安全: 0

星标: 4

关注者: 6

分支: 4

开放问题: 11

语言:Twig

类型:symfony-bundle

4.0.0 2024-09-09 08:19 UTC

README

此包被用于各种TYPO3 Symfony应用程序,以确保流畅的视觉体验和减少维护。

安装

composer require t3g/symfony-template-bundle

确保在您的 composer.json 文件中包含 symfony 默认脚本。

{
    "scripts": {
        "auto-scripts": {
            "cache:clear": "symfony-cmd",
            "assets:install %PUBLIC_DIR%": "symfony-cmd"
        },
        "post-install-cmd": [
            "@auto-scripts"
        ],
        "post-update-cmd": [
            "@auto-scripts"
        ]
    }
}

配置

该包包含合理的默认配置,如下所示。如果您需要更改这些选项,可以定义这些选项

# config/packages/template.yaml
template:
    application:
        # Example: Intercept
        name: 'Template Bundle'
        # Example: intercept
        platformkey: ~
        copyright:
            author: TYPO3 GmbH
            url: https://typo3.com
        routes:
             # Example: app_index
            home: app_index
            privacy: https://typo3.com/privacy-policy
            legal: https://typo3.com/legal-notice
            feedback: https://support.typo3.com
        menu:
            # Example: App\Menu\MenuBuilder
            class: T3G\Bundle\TemplateBundle\Menu\MenuBuilder
        assets:
            # Example: app
            encore_entrypoint: ~
        email:
            legal_footer: |
                TYPO3 GmbH, Emanuel-Leutze-Straße 11, DE-40547 Düsseldorf, Germany
                Phone: +49 (0)211 20 54 36 0, Web: www.typo3.com, Email: info@typo3.com

                Court of registration: Amtsgericht Düsseldorf HRB 77950
                CEO: Daniel Fau,  (CTO & Procuration) Frank Nägler
                Supervisory Board: Olivier Dobberkau, Ric van Westhreenen, Stefan Busemann
        theme:
            # Example: md
            navbar_breakpoint: lg
            use_logo: false
            background: light
bin/console config:dump-reference template

配置将在模板中可用,并且可以通过 template 变量访问。

示例

<title>{% block title %}{% endblock %} - {{ template.application.name }}</title>
<a class="navbar-brand" href="{{ path(template.application.routes.home) }}">
    <i class="fab fa-typo3 text-primary"></i>
    <strong>{{ template.application.name }}</strong>
</a>

Encore

composer require symfony/webpack-encore-bundle

要启用您的 encore 入口点,只需在 yaml 配置中配置密钥。

# config/packages/template.yaml
template:
    application:
        assets:
            encore_entrypoint: app

扩展菜单

# config/packages/template.yml
template:
    application:
        menu:
            class: App\Menu\MenuBuilder
<?php
namespace App\Menu;

use T3G\Bundle\TemplateBundle\Menu\MenuBuilder as TemplateMenuBuider;

class MenuBuilder extends TemplateMenuBuider
{
    public function mainDefault(array $options)
    {
        $menu = parent::mainDefault($options);
        $menu->addChild(
            'home',
            [
                'route' => 'app_index',
                'label' => 'Home',
                'extras' => [
                    'icon' => 'home',
                ],
            ]
        );
        return $menu;
    }
}

可以覆盖 mainDefaultmainProfilemainFooter 的方法。

分割菜单

$menu->addChild($this->getDivider());

页面模板

扩展默认布局

{% extends '@Template/layout.html.twig' %}

可用块

标题

{% block title %}Home{% endblock %}
<title>Home - {{ template.application.name }}</title>

标题栏

如果在该模板中定义,此块将 在正文块上方渲染。

{% block headline %}Super Headline{% endblock %}
<div class="page-wrapper">
    <!-- HEADER -->
    <!-- FLASHMESSAGES -->
    <main class="page-main">
        <div class="content-section content-section-small bg-primary text-white">
            <div class="container">
                <h1 class="h2">Super Headline</h1>
            </div>
        </div>
        <!-- BODY BLOCK -->
    </main>
    <!-- FOOTER -->
</div>

正文

{% block body %}
    <div class="content-section">
        <div class="container">
            BODY CONTENT
        </div>
    </div>
{% endblock %}
<div class="page-wrapper">
    <!-- HEADER -->
    <!-- FLASHMESSAGES -->
    <main class="page-main">
        <!-- HEADLINE -->
        <div class="content-section">
            <div class="container">
                BODY CONTENT
            </div>
        </div>
    </main>
    <!-- FOOTER -->
</div>

页脚

{% block footer %}
    <div class="content-section">
        <div class="container">
            FOOTER CONTENT
        </div>
    </div>
{% endblock %}
<div class="page-wrapper">
    <!-- HEADER -->
    <!-- FLASHMESSAGES -->
    <!-- MAIN HEADLINE AND BODY -->
    <footer class="page-footer">
        <div class="content-section">
            <div class="container">
                FOOTER CONTENT
            </div>
        </div>
        <!-- COPYRIGHT AND FOOTER MENU -->
    </footer>
</div>

样式表

样式表块将在 baseencore css 之后、关闭 </head> 之前渲染。

JavaScript

JavaScript 块将在 baseencore JavaScript 之后、关闭 </body> 之前渲染。

电子邮件模板

扩展默认布局

{% extends '@Template/email.html.twig' %}

可用块

电子邮件主题

{% block email_subject %}Reset Your Password{% endblock %}

电子邮件纯文本

{% block email_plaintext %}
Forgot your password? Let's get you a new one.

We got a request to change the password for the account with the username {{ user.username }}.

You can reset your password by accessing {{ confirmationUrl }}

If you don't want to reset your password, you can ignore this email.
{% endblock %}

电子邮件HTML预览

{% block email_html_preview %}
You requested a password reset for your account.
{% endblock %}

电子邮件HTML正文

{% block email_html_body %}
<h3>Forgot your password?<br>Let's get you a new one.</h3>
<p>We got a request to change the password for the account with the username <strong style="color: #222222;">{{ user.username }}</strong>.</p>

<table border="0" cellpadding="0" cellspacing="0" width="100%" class="buttonBlock" style="min-width:100%;">
    <tbody class="buttonBlockOuter">
        <tr>
            <td style="padding-top: 36px; padding-right:18px; padding-bottom:36px; padding-left:18px;" valign="top" align="center" class="buttonBlockInner">
                <table border="0" cellpadding="0" cellspacing="0" class="buttonContentContainer" style="border-collapse: separate !important;border-radius: 3px;background-color: #ff8700;">
                    <tbody>
                        <tr>
                            <td align="center" valign="middle" class="buttonContent" style="font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, Verdana, sans-serif; font-size: 16px; padding: 18px;">
                                <a class="button " title="Reset Your Password" href="{{ confirmationUrl }}" rel="noopener noreferrer" target="_blank" style="font-weight: bold;letter-spacing: -0.5px;line-height: 100%;text-align: center;text-decoration: none;color: #FFFFFF;">Reset Your Password</a>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </td>
        </tr>
    </tbody>
</table>

<p style="font-size: 12px;">Or reset your password using this link: {{ confirmationUrl }}</p>
<p style="font-size: 12px;">If you don't want to reset your password, you can ignore this email.</p>
{% endblock %}

工具

AvatarUtility::getAvatar(string $email, int $size)

<?php
use T3G\Bundle\TemplateBundle\Utility\AvatarUtility;
echo AvatarUtility::getAvatar('info@typo3.com', 32);
// <img src="https://...avatar.png" class="avatar" height="32" width="32">

AvatarUtility::getAvatarUrl(string $email, int $size)

<?php
use T3G\Bundle\TemplateBundle\Utility\AvatarUtility;
echo AvatarUtility::getAvatarUrl('info@typo3.com', 32);
// https://...avatar.png

Twig 扩展

AutolinkExtension

autolink

Twig 过滤器可自动将网址、电子邮件和电话号码转换为链接。

{{ value|autolink }}

或者

{% apply autolink %}
    <p>
        Phone: +49 (0)211 205436-0<br>
        Web: www.typo3.com<br>
        Email: info@typo3.com
    </p>
{% endapply %}
<p>
    Phone: <a href="tel:+492112054360">+49 (0)211 205436-0</a><br>
    Web: <a href="https://www.typo3.com" target="_blank" rel="noopener">www.typo3.com</a><br>
    Email: <a href="mailto:info@typo3.com">info@typo3.com</a>
</p>

AvatarExtension

avatar

Twig 函数用于显示头像。

{{ avatar('info@typo3.com', 32) }}
<img src="https://...avatar.png" class="avatar" height="32" width="32">

IconExtension

icon

Twig 函数用于显示 typo3 图标。

{{ icon('actions-heart', 'auto') }}
<span class="icon icon-size-auto icon-state-default">
    <span class="icon-markup">
        <svg role="img" class="icon-color"><use xlink:href="/bundles/template/icons/sprites/actions.svg#actions-heart"></use></svg>
    </span>
</span>

MarkdownExtension

markdown

Twig 函数用于将 markdown 渲染为 HTML。

{{ value|markdown }}

TemplateExtension

template_function_exist

一个用于检查当前 Twig 环境中是否存在函数的函数。

{% if template_function_exist('relativetime') %}
    The relativetime function is available.
{% endif %}

template_function_call

Twig 总是检查模板中的所有函数,即使在条件中也是如此。此函数是围绕原始函数调用包装的包装器,仅在函数实际存在时执行。

# Template will still work if `encore_entry_link_tags` is not defined, function just returns null.
{{ template_function_call('encore_entry_link_tags', template.application.assets.encore_entrypoint) }}

# Template will fail if `encore_entry_link_tags` is not registered.
{{ encore_entry_link_tags(template.application.assets.encore_entrypoint) }}

DateTimeExtension

to_datetime

将 Unix 时间戳转换为日期时间对象。

{{ to_datetime(timestamp) }}

localdate

返回表示此日期的本地化字符串。

{{ localdate(datetimeObject) }}

localdatetime

返回表示此日期时间的本地化字符串。

{{ localdatetime(datetimeObject) }}

relativetime

返回相对于现在的字符串表示,例如“两天后”。默认向下舍入。

有关可能的值,请参阅 luxon 文档

用法

{{ relativetime(datetimeObject) }}

示例

使用特定的时间单位。

{{ relativetime(datetimeObject, ['minutes', 'seconds']) }}

timediff

返回表示日期与现在()之间差异的字符串,例如“1年11个月”。

{{ timediff(datetimeObject) }}

Twig 标签

frame

用法

{% frame with options %}Inner Content{% endframe %}

示例

{% frame with { id: 'identifier', color: 'primary', center: true } %}
    <p class="lead">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
{% endframe %}
<div id="identifier" class="frame frame-size-default frame-background-primary frame-no-backgroundimage frame-space-before-none frame-space-after-none">
    <div class="frame-container">
        <div class="frame-inner text-center">
            <p class="lead">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
        </div>
    </div>
</div>

expand

用法

{% expand %}Inner Content{% endexpand %}

示例

{% expand %}
    <p class="lead">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
{% endexpand %}
<div class="expander">
    <input class="expander-checkbox" type="checkbox" id="expander-6267e5f76fa06">
    <label for="expander-6267e5f76fa06" class="expander-toggle">
        Show more
    </label>
    <div class="expander-content">
        <div class="expander-content-inner">
            <p class="lead">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
        </div>
    </div>
</div>

JavaScript 库

日期选择器

该库可以通过属性 data-datepicker 启用和配置,将配置作为json编码的字符串传递。

示例 HTML

<input
    type='text'
    name='date'
    placeholder='Select Date...'
    data-datepicker='{}'
    class="form-control"
>
<input
    type='text'
    name='date'
    placeholder='Select Datetime...'
    data-datetimepicker='{}'
    class="form-control"
>

示例 FormBuilder

$builder->add('date', DateType::class, [
    'widget' => 'single_text',
    'attr' => [
        'placeholder' => 'Select Date...',
        'data-datepicker' => json_encode(
            [],
            JSON_THROW_ON_ERROR
        ),
    ],
    'html5' => false
]);
$builder->add('date', DateTimeType::class, [
    'widget' => 'single_text',
    'attr' => [
        'placeholder' => 'Select Datetime...',
        'data-datetimepicker' => json_encode(
            [],
            JSON_THROW_ON_ERROR
        ),
    ],
    'html5' => false
]);

来源: https://flatpickr.js.org/

选择

该库可以通过属性 data-choicesjs 启用和配置,将配置作为json编码的字符串传递。

示例 HTML

<select
    name='country'
    data-choicesjs='{"maxItemCount":1}'
>
    <option value="">Please select a country</option>
    ...
    <option value="DE" selected="selected">Germany</option>
    <option value="GH">Ghana</option><option value="GI">Gibraltar</option>
    <option value="GL">Greenland</option><option value="GD">Grenada</option>
    ...
</select>

示例 FormBuilder

$builder->add('country', ChoiceType::class, [
    'attr' => [
        'data-choicesjs' => json_encode(
            [
                'maxItemCount' => 1,
            ],
            JSON_THROW_ON_ERROR
        ),
    ],
    'choices' => $countryChoices,
    'empty_data' => null,
    'placeholder' => 'Please select a country',
]);

来源: https://github.com/jshjohnson/Choices

标签输入

该库可以通过属性 data-taginput 启用和配置,将配置作为json编码的字符串传递。

示例 FormBuilder

$builder->add('usernames', TextType::class, [
    'attr' => [
        'data-taginput' => json_encode([], JSON_THROW_ON_ERROR),
    ],
]);

$usernames = array_map(
    function($item) { return $item['value']; },
    json_decode($form->getData()['usernames'], true)
);

来源: https://github.com/yairEO/tagify