PHPプログラムに関する各種メモ書き:タグ「Twig」での検索

PHP 7.4 で Twig を使用すると自動的に改行やスペースが削除されてしまう不具合に対応する

● PHP 7.4 で Twig を使用すると自動的に改行やスペースが削除されてしまう不具合に対応する

Lexer.php:163 を以下のように修正します

if (isset($this->positions[2][$this->position][0]) ) {
    $text = rtrim($text);
}

    ↓

if (isset($this->positions[2][$this->position][0]) && ($this->options['whitespace_trim'] === $this->positions[2][$this->position][0])) {
   $text = rtrim($text);
}
No.2037
09/10 15:23

edit

Twig

Twig で 現在の日付までのドロップダウンリストを生成する

新しい年になった時にドロップダウンリストの項目を一つ増やしたいという時があります。 Twigを使用している場合は次のように書くと現在の年までのドロップダウンリストを生成いたします

<select name="y">
	<option value="">----</option>
{% set year_start = 2010 %}
{% set year_end   = "now"|date("Y") %}
{% for i in year_start..year_end %}
	<option value="{{i}}">{{i}}</option>
{% endfor %}
</select>

↓ このように生成されます

<select name="y">
	<option value="">----</option>
	<option value="2010">2010</option>
	<option value="2011">2011</option>
	<option value="2012">2012</option>
	<option value="2013">2013</option>
	<option value="2014">2014</option>
	<option value="2015">2015</option>
	<option value="2016">2016</option>
	<option value="2017">2017</option>
</select>
No.1174
11/22 17:17

edit

Twig
日付

Twigテンプレートで動的に継承元テンプレートを変更する

Twigテンプレートで動的に継承元テンプレートを変更するには次のように一度変数にファイル名を入れて そこから呼び出します。

lang_settingen の時はファイル「base_english.html」を、それ以外の時はファイル「base_japanese.html」を継承元にするサンプル

{% if lang_setting == 'en' %}{% set base_template = 'base_english.html' %}
{% else %}{% set base_template = 'base_japanese.html' %}
{% endif %}

{% extends base_template %}
No.1171
11/07 15:41

edit

Twig

Twigで日付から日本語の曜日を返すフィルター

Twig/Extensionuser にファイル名 Youbi.php で保存します。

Youbi.php

<?php

class Twig_Extensionuser_Youbi extends \Twig_Extension
{
    public function getFilters()
    {
        return array(
            'youbi' => new \Twig_Filter_Method($this, 'youbi', array(
                'needs_environment' => true,
                'needs_context' => true,
                'is_safe' => array(
                    'evaluate' => true,
                ),
            )),
        );
    }

    public function youbi(\Twig_Environment $environment, $context, $string1)
    {
        $date = new DateTime($string1);
        $w_no = $date->format('w');
        $week = array('日', '月', '火', '水', '木', '金', '土');
        return $week[$w_no];
    }

    protected function parseString(\Twig_Environment $environment, $context, $string)
    {
        $environment->setLoader(new \Twig_Loader_String());
        return $environment->render($string, $context);
    }

    public function getName()
    {
        return 'youbi';
    }
}

● 使い方

{{'2017-08-04' | youbi }}
No.1162
09/08 15:25

edit

日付
Twig

Twigで生年月日から現在の年齢を返すフィルター

new Twig_SimpleFilter('getage', array($this, 'getage')) ,
    /**
     * 誕生日文字列( 例: 1983-12-19)から現在の年齢を返します
     *
     * @param   string      $date_name (例: '1983-12-19')
     * @return  int         現在の年齢
     */
    public function getage( $date_name )
    {
        $birth = date('Ymd', strtotime($date_name));
        $now = date("Ymd");
        return floor(($now-$birth)/10000);
    }

使い方

{{ '1983-12-19' | getage }}歳
No.1159
09/05 16:05

edit

日付
Twig

Twigのバージョンを表示する

Twigのバージョンを表示するには

<p>twigのバージョンは : {{ constant('Twig_Environment::VERSION') }}</p>

とします。

なお Twigのバージョン2 を利用するには PHP7以上が必要です。

No.1079
01/20 17:19

edit

Twig

Twigテンプレートの変数の中で変数をevalするフィルタ

Twigテンプレートの変数の中で変数をevalするフィルタがとても便利なので紹介します。

Twig > Extension > Evalute.php で保存

<?php
class Twig_Extension_Evaluate extends \Twig_Extension {
    public function getFilters( ) {
        return array(
            'evaluate' => new \Twig_Filter_Method( $this, 'evaluate', array(
                'needs_environment' => true,
                'needs_context' => true,
                'is_safe' => array(
                    'evaluate' => true
                )
            ))
        );
    }
    public function evaluate( \Twig_Environment $environment, $context, $string ) {
        $loader = $environment->getLoader( );
        $parsed = $this->parseString( $environment, $context, $string );
        $environment->setLoader( $loader );
        return $parsed;
    }
    protected function parseString( \Twig_Environment $environment, $context, $string ) {
        $environment->setLoader( new \Twig_Loader_String( ) );
        return $environment->render( $string, $context );
    }
    public function getName( ) {
        return 'evaluate';
    }
}

Twig読み込み時に以下の行を追加

$twig->addExtension( new Twig_Extension_Evaluate() );

以下のように変数の中の変数が展開できます

{% set var = 'inner variable' %}
{{'this is a string with an {{var}}'|evaluate}}

 ↓

this is a string with an inner variable

このような書き方もできます(ハッシュのメンバ名が変数の時に展開する)

$data['column_name'] = "data_id";
$data['data_hash']['data_id'] = 999;
{{data_hash[column_name]|evaluate}}

 ↓

999

引用 : http://goo.gl/Y1LlSz

No.959
11/29 23:08

edit

Twig

テンプレートエンジンTwigに自作フィルタを追加する

Twigに自作フィルタを追加するにはフィルタを定義して addFilter するだけでOKです。

例 : ファイルの存在をチェックする file_exists フィルタを追加する(PHPファイル内に以下を追加)

$filter = new Twig_SimpleFilter('file_exists', function ($filename) {
	// ディレクトリは適宜書き換えること
	return file_exists(dirname(__FILE__)."/{$filename}");
});
$twig->addFilter($filter);

使い方(HTML内で以下のように記述)

{% if "test.jpg"|file_exists  %}
	ファイルが存在します
{% else %}
	ファイルは存在しません
{% endif %}
No.955
07/02 14:18

edit

Twig
ファイル

テンプレートエンジン『Twig』と『Smarty』『Laravel Blade』比較表

● テンプレートの読み込みとディレクトリのセット(PHPファイルに記述)

※ Smarty

require_once('Smarty/Smarty.class.php');
$smarty = new Smarty();
$smarty->template_dir = './templates/';
$smarty->compile_dir = './templates_c/';

※ Twig

require_once('Twig/Autoloader.php');
Twig_Autoloader::register();
$loader = new Twig_Loader_Filesystem("./templates/");
$twig = new Twig_Environment($loader, array(
	'cache' => 'cache_twig',
	 'debug' => false ,
));

● 変数のアサイン(PHPファイルに記述)

※ Smarty

$smarty->assign( array("mydata" => $hoge) );

※ Twig

$twig->addGlobal( "mydata", $hoge );

● 変数のアサイン(テンプレートファイルに記述)

※ Smarty

{assign var="aaa" value="999" }

※ Twig

{% set aaa = '999' %}

※ Twig(ヒアドキュメント的)

{% set aaa %}
    <div id="pagination">
        ...
    </div>
{% endset %}

※ Laravel Blade

@php($aaa = 999)

または

@php $aaa = 999; @endphp

または

@php
$aaa = 999;
@endphp

● テンプレートの表示(PHPファイルに記述)

※ Smarty

$template_file = 'myfile.html';
$smarty->display( $template_file );

※ Twig

$hash = array(
'id' => 999 ,
'name' => 'hoge' ,
);
$template_file = 'myfile.html'
echo $twig->render($template_file, $hash);

● テンプレートの継承(レイアウトテンプレートに記述)

※ Twig

{% block content %}
{% endblock %}

※ Laravel Blade

@yield('content')

● テンプレートの継承(子テンプレートに記述)

※ Twig

{% extends "layout" %}

{% block content %}
{% endblock %}

※ Laravel Blade

@extends('layout')
@extends('layout.blade.php') // ファイル名で記述してもok

@section('content')
@endsection

● ループ処理(for 文)(HTMLファイル内に記述)

※ Smarty

{section name=i start=0 loop=10}
  {$smarty.section.i.index}回目
{/section}

※ Twig

{% for i in 0..10 %}
  {{ i }}回目
{% endfor %}

※ Laravel Blade

@for ($i = 0; $i < 10; $i++)
    {{ $i }}回目
@endfor

● ループ処理(foreach 文)とループ回数(HTMLファイル内に記述)

※ Smarty

{ foreach from=$my_loop key="k" item="v" }
{$v.user_name}
{ /foreach }

※ Twig

{% for k,v in my_loop %}
  <h1>{{ loop.index }}番目</h1>
  {% if loop.first %}最初の要素です。
  {% elseif loop.last %}最後の要素です。
  {% else %}{{ v.user_name }}
  {% endif %}   
{% endfor %}

Twig の loop.index1 から始まります。

※ Laravel Blade ( foreach )

@foreach ($users as $user)
    {{$loop->index}}

    @if ($loop->first)
        これは最初の要素です
    @endif

    @if ($loop->last)
        これは最後の要素です
    @endif

    <p>これは {{ $user->id }} ユーザーです。</p>
@endforeach

Laravel Blade の $loop->index0 から始まります。

※ Laravel Blade ( forelse )おすすめ

@empty が使用できるのでこちらの方がオススメの記法です

@forelse ($users as $user)
    {{$loop->index}}

    @if ($loop->first)
        これは最初の要素です
    @endif

    @if ($loop->last)
        これは最後の要素です
    @endif

    <p>これは {{ $user->id }} ユーザーです。</p>
@empty
    ユーザーはいません
@endforelse

なお @empty は省略できません。
また、Laravel Blade の $loop->index0 から始まります。

● ファイルのインクルード(HTMLファイル内に記述)

※ Smarty

{include file="inc/header.html"}

※ Twig

{% include 'inc/header.html' %}

※ Laravel Blade

resources/views/user/mypage_sub_menu.blade.php を読み込みます

@include('user.mypage_sub_menu')

● if文(HTMLファイル内に記述)

※ Smarty

{if $flag==1 and hoge == 'myname'}
     hogehoge
{else}
    fugafuga
{/if}

※ Twig

{% if flag == 1 and hoge == 'myname' %}
     hogehoge
{% else %}
    fugafuga
{% endif %}

※ Laravel Blade

@if ( flag == 1 and hoge == 'myname' )
     hogehoge
@elseif ( flag == 2 )
     hogehoge2
@else
    fugafuga
@endif

● コメントアウト(HTMLファイル内に記述)

※ Smarty

{*
ここの間に記述したものはコメントアウトされ表示されません
*}

※ Twig

{#
ここの間に記述したものはコメントアウトされ表示されません
#}

※ Laravel Blade

{{--
ここの間に記述したものはコメントアウトされ表示されません
--}}

● 文字列のエスケープ(HTMLファイル内に記述)

※ Smarty(エスケープオプションは : html, htmlall, url, urlpathinfo, quotes, hex, hexentity, javascript, mail )

<a href="{$data|escape:'url'}">クリック</a>

※ Twig(エスケープオプションは : html, js, css, url, html_attr )

<a href="{{data|escape('url') }}">クリック</a>
<a href="{{data|e('url') }}">クリック</a> {# 【e】 だけでも OK #}

● 文字列のエスケープなし(HTMLファイル内に記述)

※ Laravel Blade

Hello, {!! $name !!}.

● 日付の表示(HTMLファイル内に記述)

※ Smarty

{* 2015-07-30 13:04:58 みたいな表示 *}
{$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}

※ Twig

{# 2015-07-30 13:04:58 みたいな表示 #}
{{ "now"|date("Y-m-d H:i:s") }}
{# TIMEZONE を指定することもできます #}
{{ "now"|date('d/m/Y H:i', timezone="Europe/Paris") }}

Twig の dateフィルタの 注意
データベースなどから持ってきた日付けを整形する場合はデータが存在するかどうかチェックしてから表示しないと、 データが存在しない場合に 現在の日付が表示されてしまいます

{{ "" | date("Y年m月d日") }} // 現在の日付が表示されます

例1 : if 文で判別する

{% if v.added_date != "" %}{{ v.added_date | date("Y/m/d H:i") }}{% endif %}

例2 : 三項演算子で表示する

{{ v.added_date is empty ? "" : v.added_date | date("Y/m/d") }}

● ホワイトスペースと改行をなくして1行で出力する(HTMLファイル内に記述)

※ Smarty

{strip}
<table>
 <tr>
  <td>
   test
  </td>
 </tr>
</table>
{/strip}

※ Twig

{% spaceless %}
<table>
 <tr>
  <td>
   test
  </td>
 </tr>
</table>
{% endspaceless %}

※ Laravel Blade ( PHPコードを直接記述する事ができます )

<?php $aaa = 999; ?>

● テンプレートファイル内で配列の長さを知る(HTMLファイル内に記述)

※ Smarty

{$test_loop|@count}

※ Twig

{{ test_loop |length }}

● 長い文字列を切り詰める(truncate)(HTMLファイル内に記述)

※ Smarty

{"abcdefghijklmnopqrstuvwxyz"|truncate:10}

※ Twig

Twigで truncate を使うには Twig-extensions をインストールします
https://github.com/twigphp/Twig-extensions
からダウンロードして Extensions ディレクトリを Twigディレクトリの下にアップロードし
PHPで $twig->addExtension( new Twig_Extensions_Extension_Text() ); とします。

{{"abcdefghijklmnopqrstuvwxyz"| truncate(20)}}

Twig_Extensions_Extension_Text : http://bit.ly/2jfkzXw

● 文字列の分割(explode, split)(HTMLファイル内に記述)

※ Smarty

{assign var="new_array" value=","|explode:$str_hoge} 

※ Twig

{% set new_array = "one,two,three"|split(',') %}

● 文字列の置換(replace)(HTMLファイル内に記述)

※ Twig

{{ "my name is hogehoge" | replace({hoge':'fuga'}) }}

● 文字列を逆にする(HTMLファイル内に記述)

※ Twig

{{ '1234'|reverse }}
{# outputs 4321 #}

● 文字列を切り出す(HTMLファイル内に記述)

※ Twig

{{ 123456 | slice(0, 2) }}

● 文字列の連結(HTMLファイル内に記述)

※ Smarty

{ 'sugoude'|cat:'DJ'|cat:'Master Key'}

※ Twig

{{ 'sugoude' ~ 'DJ' ~ 'Master Key' }}

連結した文字にフィルタをかける場合は、文字列を定義してからフィルタをかけましょう

× NG

{{ $hoge~$fuga|my_filter }}

◯ OK

{%set hogefuga = $hoge~$fuga%}
{{ $hogefuga|my_filter }}

● printf , sprintf(プリントフォーマット)(HTMLファイル内に記述)

※ Smarty

{ $value | string_format:"%02d" }

※ Twig

{{ "%02d" | format(value) }}

● テンプレートファイル名を取得する

※ Smarty

{$smarty.template}

※ Twig

{{ _self.getTemplateName().__toString }}

※ Gulp Twig と PHP Twig 両方に対応したファイル名取得

{# テンプレートファイル名 #}
{% if _target.relative %}{% set template_filename = _target.relative %}
{% else %}{% set template_filename = _self.getTemplateName().__toString %}
{% endif %}

● アプリのトップURIを取得

※ Laravel Blade

{{ url('/') }}

または

{{Request::root()}}

 Twig リファレンス : http://git.io/vneJa 

No.954
06/12 21:46

edit

Twig
Smarty
Gulp