「PHPの基礎 - テンプレート方式」の版間の差分

提供: MochiuWiki : SUSE, EC, PCB

118行目: 118行目:


== テンプレートエンジンの使用 ==
== テンプレートエンジンの使用 ==
Smarty、Twig等のテンプレートエンジンを使用する方法がある。
Smarty、Twig等のテンプレートエンジンを使用する方法がある。<br>
これらは独自の構文を持ち、より柔軟なテンプレート制御が可能である。<br>
これらは独自の構文を持ち、より柔軟なテンプレート制御が可能である。<br>
<br>
<br>
* Twigを使用する場合
==== Twigを使用する場合 ====
  <syntaxhighlight lang="php">
  <syntaxhighlight lang="php">
  // index.php
  // index.php
149行目: 149行目:
  </body>
  </body>
  </html>
  </html>
</syntaxhighlight>
<br>
==== Laravelを使用する場合 ====
LaravelのBladeテンプレートエンジンは、PHPの機能を損なうことなく、保守性の高いテンプレートを作成できる機能を提供している。<br>
<br>
Bladeテンプレートの特徴を以下に示す。<br>
* @extends、@section、@yield によるレイアウトの継承
* {{ }} による変数の出力 (自動エスケープ付き)
* {!! !!} によるHTMLエスケープなしの出力
* @if、@foreach等のディレクティブ
* コンポーネントによる再利用可能なUI部品の作成
* バリデーションエラーの表示が簡単
* @auth、@guest等の認証関連ディレクティブ
<br>
* Bladeの基本的な構造
<syntaxhighlight lang="php">
// routes/web.php
Route::get('/', function () {
    return view('welcome', [
      'title'  => 'Webサイトのタイトル',
      'content' => 'ここに本文を入れる'
    ]);
});
</syntaxhighlight>
<br>
<syntaxhighlight lang="php">
// resources/views/layouts/app.blade.php
<!DOCTYPE html>
<html>
<head>
    <title>@yield('title')</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    @vite([
      'resources/css/app.css',
      'resources/js/app.js'
    ])
</head>
<body>
    <header>
      @include('layouts.navigation')
    </header>
    <main>
      @yield('content')
    </main>
    <footer>
      @include('layouts.footer')
    </footer>
</body>
</html>
</syntaxhighlight>
<br>
<syntaxhighlight lang="php">
// resources/views/welcome.blade.php
@extends('layouts.app')
@section('title', $title)
@section('content')
    <div class="container">
      <h1>{{ $title }}</h1>
      <p>{{ $content }}</p>
      {{-- 条件分岐の例 --}}
      @if (Auth::check())
          <p>ようこそ、{{ Auth::user()->name }}さん</p>
      @else
          <p>ログインしてください</p>
      @endif
      {{-- ループの例 --}}
      @foreach ($items as $item)
          <div class="item">
            {{-- エスケープなしで出力する場合 --}}
            {!! $item->description !!}
          </div>
      @endforeach
    </div>
@endsection
</syntaxhighlight>
<br>
* コンポーネントの使用例
<syntaxhighlight lang="php">
// resources/views/components/button.blade.php
<button {{ $attributes->merge(['class' => 'btn']) }}>
    {{ $slot }}
</button>
</syntaxhighlight>
<br>
<syntaxhighlight lang="php">
// resources/views/welcome.blade.php での使用例
<x-button class="btn-primary">
    クリックしてください
</x-button>
</syntaxhighlight>
<br>
* 共通パーツの分離例
<syntaxhighlight lang="php">
// resources/views/layouts/navigation.blade.php
<nav>
    <ul>
      <li><a href="{{ route('home') }}">ホーム</a></li>
      <li><a href="{{ route('about') }}">会社概要</a></li>
      <li><a href="{{ route('contact') }}">お問い合わせ</a></li>
    </ul>
</nav>
  </syntaxhighlight>
  </syntaxhighlight>
<br><br>
<br><br>

2024年11月8日 (金) 17:20時点における版

概要

テンプレート方式とは、HTMLのデザイン部分とPHPのロジック部分を分離することである。
これにより、デザイナと開発者が別々に作業しやすくなり、コードの保守性も向上する。

テンプレート方式を採用する主なメリットを以下に示す。

  • コードの可読性向上
  • メンテナンス性の向上
  • チーム開発での作業効率向上
  • デザインの一貫性維持が容易


代表的なテンプレートの実装方法を以下に示す。

  • 基本的な分離方式
    PHPファイルとHTMLファイルを分けて、includeで結合する。
  • テンプレートエンジンの使用
    Smarty、Twig等のテンプレートエンジンを使用する。


なお、テンプレート方式を導入する場合は、プロジェクトの規模や要件に応じて適切な方法を選択することが重要である。
小規模なプロジェクトの場合は基本的な分離方式で十分の可能性があり、大規模なプロジェクトではテンプレートエンジンの採用を検討する。


基本的な分離方式

PHPファイルとHTMLファイルを分けて、include文で結合する方法である。

 // index.php
 
 <?php
    $title   = "Webサイトのタイトル";
    $content = "ここに本文を入力する";
 
    include 'template.html';
 ?>


 <!-- template.html -->
 
 <!DOCTYPE html>
 <html>
 <head>
    <!-- 変数titleを使用する -->
    <title><?php echo $title; ?></title>
 </head>
 <body>
    <!-- 変数contentを使用する -->
    <?php echo $content; ?>
 </body>
 </html>



レイアウトの共通化

ヘッダ部やフッタ部では、共通部分を別ファイルとして管理することにより、保守性が向上する。

 // header.php
 
 <!DOCTYPE html>
 <html>
 <head>
    <!-- 必要に応じて、ヘッダ部分で変数を確認する処理を入れる -->
    <?php
       if (!isset($title)) {
          $title = "デフォルトタイトル";
       }
    ?>
    <title><?php echo $title; ?></title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="/css/style.css">
 </head>
 <body>
    <header>
       <nav>
          <ul>
             <li><a href="/">ホーム</a></li>
             <li><a href="/about">会社概要</a></li>
             <li><a href="/contact">お問い合わせ</a></li>
          </ul>
       </nav>
    </header>


 // footer.php
 
    <footer>
       <div class="footer-content">
          <p>&copy; 2024 会社名 All Rights Reserved.</p>
       </div>
    </footer>
    <script src="/js/main.js"></script>
 </body>
 </html>


 // content.php (このファイルをトップページとする)
 
 <?php
   $title = "ページタイトル";
 
   include 'header.php';
 ?>
 
 <!-- メインコンテンツ -->
 <main>
 <div class="content">
    <h1>ようこそ</h1>
    <p>これはメインコンテンツです。</p>
 </div>
 </main>
 
 <?php
    include 'footer.php';
 ?>



テンプレートエンジンの使用

Smarty、Twig等のテンプレートエンジンを使用する方法がある。
これらは独自の構文を持ち、より柔軟なテンプレート制御が可能である。

Twigを使用する場合

 // index.php
 
 <?php
 require_once 'vendor/autoload.php';
 
 $loader = new \Twig\Loader\FilesystemLoader('templates');
 $twig = new \Twig\Environment($loader);
 
 echo $twig->render('template.twig', [
    'title'   => 'Webサイトのタイトル',
    'content' => 'ここに本文を入力する'
 ]);


 {# template.twig #}
 
 <!DOCTYPE html>
 <html>
 <head>
    <title>{{ title }}</title>
 </head>
 <body>
    {{ content }}
 </body>
 </html>


Laravelを使用する場合

LaravelのBladeテンプレートエンジンは、PHPの機能を損なうことなく、保守性の高いテンプレートを作成できる機能を提供している。

Bladeテンプレートの特徴を以下に示す。

  • @extends、@section、@yield によるレイアウトの継承
  • {{ }} による変数の出力 (自動エスケープ付き)
  • {!! !!} によるHTMLエスケープなしの出力
  • @if、@foreach等のディレクティブ
  • コンポーネントによる再利用可能なUI部品の作成
  • バリデーションエラーの表示が簡単
  • @auth、@guest等の認証関連ディレクティブ


  • Bladeの基本的な構造
 // routes/web.php
 
 Route::get('/', function () {
    return view('welcome', [
       'title'   => 'Webサイトのタイトル',
       'content' => 'ここに本文を入れる'
    ]);
 });


 // resources/views/layouts/app.blade.php
 
 <!DOCTYPE html>
 <html>
 <head>
    <title>@yield('title')</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    @vite([
       'resources/css/app.css',
       'resources/js/app.js'
    ])
 </head>
 <body>
    <header>
       @include('layouts.navigation')
    </header>
 
    <main>
       @yield('content')
    </main>
 
    <footer>
       @include('layouts.footer')
    </footer>
 </body>
 </html>


 // resources/views/welcome.blade.php
 
 @extends('layouts.app')
 
 @section('title', $title)
 
 @section('content')
    <div class="container">
       <h1>{{ $title }}</h1>
       <p>{{ $content }}</p>
 
       {{-- 条件分岐の例 --}}
       @if (Auth::check())
          <p>ようこそ、{{ Auth::user()->name }}さん</p>
       @else
          <p>ログインしてください</p>
       @endif
 
       {{-- ループの例 --}}
       @foreach ($items as $item)
          <div class="item">
             {{-- エスケープなしで出力する場合 --}}
             {!! $item->description !!}
          </div>
       @endforeach
    </div>
 @endsection


  • コンポーネントの使用例
 // resources/views/components/button.blade.php
 
 <button {{ $attributes->merge(['class' => 'btn']) }}>
    {{ $slot }}
 </button>


 // resources/views/welcome.blade.php での使用例
 
 <x-button class="btn-primary">
    クリックしてください
 </x-button>


  • 共通パーツの分離例
 // resources/views/layouts/navigation.blade.php
 
 <nav>
    <ul>
       <li><a href="{{ route('home') }}">ホーム</a></li>
       <li><a href="{{ route('about') }}">会社概要</a></li>
       <li><a href="{{ route('contact') }}">お問い合わせ</a></li>
    </ul>
 </nav>