0
0

More than 1 year has passed since last update.

テンプレート(smarty, mustache, BladeOne)をPHPファイルに適用する

Last updated at Posted at 2022-08-07

概要

PHPファイル自身をsmartyやmustache等のテンプレートエンジンのテンプレートとして適用できるのかという思考実験をしてみたら簡単にできたので公開してみる。

何がうれしいの?

テンプレートエンジンを実行してテンプレートを展開するコードをテンプレートに埋め込めれば、
PHPファイル1つ(テンプレートエンジン本体のソースコードを除く)でテンプレートの実行結果が確認できてテンプレートの製作がはかどりそうと思った。

やり方

PHPファイル本体はfile_get_contents(__FILE__)で取得できるので、PHP部分<? ~ ?>を正規表現で取り除いてからテンプレートエンジンに渡すだけ。

なぜsmartyとmustache?

どちらも最悪ZIP解凍したファイル群をフォルダごとアップロードするだけでテンプレートエンジンの実行ができるから。
だいたいのテンプレートエンジンはそうなのかもしれないけど。要はたまたま目についただけ。
一応mustacheは他の言語というかJavaScriptにも公式対応しているので夢が広がりそうと思った部分もある。

コード

smartyの場合

smarty.php
<?php
$result = ['test' => 'テスト'];

if ($_SERVER['REQUEST_METHOD'] == "GET") {
    //PHP部分を取り除くプリフィルタ
    function phpfilter($source)
    {
        return preg_replace('/\<\?(.*?)[?]>/s', '', $source);
    }
    define('SMARTY_DIR', '/var/www/html/php/Smarty/libs/');
    require_once(SMARTY_DIR . 'Smarty.class.php');
    $smarty = new Smarty();
    $smarty->template_dir = './';
    $smarty->compile_dir = './output';
    $smarty->registerFilter('pre', 'phpfilter'); //プリフィルタの設定
    $smarty->assign('result', $result);
    $smarty->display(__FILE__); //このファイル自身をテンプレートにしてレンダリング。
} else {
    echo json_encode($result);
}
exit;
?>
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>{$result.test}</title>
</head>

<body>
    {$result.test}
</body>

</html>

Mustacheの場合

mustache.php
<?php

$data = ['test' => 'テスト'];

//Mustacheエンジンのロード
require_once('/var/www/html/php/Mustache/Autoloader.php');
Mustache_Autoloader::register();
$engine = new Mustache_Engine(array(
    'loader' => new Mustache_Loader_StringLoader(),
    'partials_loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__)),
), array('entity_flags' => ENT_QUOTES));

$source = file_get_contents(__FILE__);    //自分自身のファイルを取得
$source = preg_replace('/\<\?(.*?)[?]>/s', '', $source); //PHPコード部分を削除
$contents = $engine->render($source, $data); //PHPコードを削除した文字列をテンプレートにレンダリング
echo $contents;
exit();
?>
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>{{test}}</title>
</head>

<body>
    {{test}}
</body>

</html>

BladeOneの場合
laravelから切り離したBladeテンプレート独立版なんてのがあったんですね

bladeone.php
<?php

$data = ['name' => 'World'];

include __DIR__.'/lib/BladeOne.php';
use eftec\bladeone\BladeOne;
class CustomBladeOne extends BladeOne
{
    //getFileを継承してテンプレートファイルを加工する
    public function getFile($fullFileName): string
    {
        $source = parent::getFile($fullFileName);
        $source = preg_replace('/\<\?(.*?)[?]>/s', '', $source); //PHPコード部分を削除
        return $source;
    }
}
$blade = new CustomBladeOne(__DIR__, __DIR__.'/compiles');
$blade->setFileExtension('.php');
$contents = $blade->run(basename(__FILE__, '.php'), $data);
echo $contents;
exit;
?>
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Bladeテンプレートのテスト。</title>
</head>
<body>
<h1>Bladeテンプレートのテスト。</h1>
<p>Hello, {{$name}}.</p>
</body>
</html>

実装した感想

mustache版を実装して思ったことは、これリクエストに応じて適用済みのテンプレートを返したりテンプレートだけを返してJavascript側でテンプレート適用させたりすればSSR付きのSPAっぽいことできるんじゃね?って思いました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0