symfony4:Twigの拡張

#FormTheme設定
##bootstrap_4_horizontal_layout.html.twigを利用
```/config/packages/twig.yaml
twig:
    form_themes: ['bootstrap_4_horizontal_layout.html.twig']
```
##bootstrap_4_horizontal_layout.html.twigを拡張

関連)
■form_div_layout.html.twig
https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig

■bootstrap_base_layout.html.twig
https://github.com/symfony/twig-bridge/blob/master/Resources/views/Form/bootstrap_base_layout.html.twig

■bootstrap_4_layout.html.twig
https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig

■bootstrap_4_horizontal_layout.html.twig
https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_horizontal_layout.html.twig


###テンプレート作成
ex)エラーの表示個所を変更

```/templates/extends/bootstrap_form.html.twig
{% use "bootstrap_4_horizontal_layout.html.twig" %}

{% block form_label -%}
{%- if label is same as(false) -%}
        <div class="{{ block('form_label_class') }}"></div>
    {%- else -%}
        {%- if expanded is not defined or not expanded -%}
            {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' col-form-label')|trim}) -%}
        {%- endif -%}
        {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ block('form_label_class'))|trim}) -%}
    {% if label is not same as(false) -%}
        {%- if compound is defined and compound -%}
            {%- set element = 'legend' -%}
            {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' col-form-label')|trim}) -%}
        {%- else -%}
            {%- set label_attr = label_attr|merge({for: id}) -%}
        {%- endif -%}
        {% if required -%}
            {% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) %}
        {%- endif -%}
        {% if label is empty -%}
            {%- if label_format is not empty -%}
                {% set label = label_format|replace({
                    '%name%': name,
                    '%id%': id,
                }) %}
            {%- else -%}
                {% set label = name|humanize %}
            {%- endif -%}
        {%- endif -%}
        <{{ element|default('label') }}{% if label_attr %}{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}{% endif %}>
        {%- if translation_domain is same as(false) -%}
            {%- if label is same as(false) -%}
                {{- label -}}
            {%- else -%}
                {{- label|raw -}}
            {%- endif -%}
        {%- else -%}
            {%- if label is same as(false) -%}
                {{- label|trans(label_translation_parameters, translation_domain) -}}
            {%- else -%}
                {{- label|trans(label_translation_parameters, translation_domain)|raw -}}
            {%- endif -%}
        {%- endif -%}
        {#
        以下削除
        {% block form_label_errors %}{{- form_errors(form) -}}{% endblock form_label_errors %}
        #}
        </{{ element|default('label') }}>
    {%- else -%}
        {%- if errors|length > 0 -%}
        <div id="{{ id }}_errors" class="mb-2">
            {{- form_errors(form) -}}
        </div>
        {%- endif -%}
    {%- endif -%}
{%- endif -%}
{%- endblock form_label %}

{%- block form_widget -%}
    {% if compound %}
        {{- block('form_widget_compound') -}}
    {% else %}
        {{- block('form_widget_simple') -}}
    {% endif %}
    {# 以下追加 #}
    {% block form_label_errors %}{{- form_errors(form) -}}{% endblock form_label_errors %}
{%- endblock form_widget -%}
```
```/config/packages/twig.yaml
twig:
#    form_themes: ['bootstrap_4_horizontal_layout.html.twig']
     form_themes: ['extends/bootstrap_form.html.twig']
```
#Twig\Extension\AbstractExtensionを拡張
```
namespace App\Twig;

use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use App\Entity\Form;

class FormTwigExtension extends AbstractExtension
{
    public function getFilters() {
        return [
            new TwigFilter('getType' , [$this,'typeFilter']),
            new TwigFilter('year' , [$this,'yearFilter']),
        ];
    }


    public function typeFilter(int $typeId = 0):string
    {
        $num = 0;
        if(isset(Form::TYPE_CHOICES[$typeId])){
            $num = $typeId;
        }
        return Form::TYPE_CHOICES[$num];
    }

    public function yearFilter(int $year = 0,string $after = "年度"):string
    {
        if($year === 0){
            return "";
        }else{
            return $year . $after;
        }
    }
}
```
#Twig
```
{{ type|getType }}
{{ year|year }}
{{ year|year('年') }}
```

```
/**
 * @Route("/blog/{post_id}")
 * @ParamConverter("post", options={"id" = "post_id"})
 */
public function showPost(Post $post) {}
```
##MEMO
###tranrator関連
https://qiita.com/nagi125/items/7e474a6d4a8001a3759e