Working with Server Side Includes

In a similar way as ESI (Edge Side Includes), SSI can be used to control HTTP caching on fragments of a response. The most important difference that is SSI is known directly by most web servers like Apache, Nginx etc.

ESI (エッジ サイド インクルード) と同様に、SSI を使用して応答のフラグメントの HTTP キャッシングを制御できます。SSI の最も重要な違いは、Apache、Nginx などのほとんどの Web サーバーによって直接認識されます。

The SSI instructions are done via HTML comments:

SSI 命令は、HTML コメントを介して行われます。
1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
    <body>
        <!-- ... some content -->

        <!-- Embed the content of another page here -->
        <!--#include virtual="/..." -->

        <!-- ... more content -->
    </body>
</html>

There are some other available directives but Symfony manages only the #include virtual one.

他にも利用可能なディレクティブがいくつかありますが、Symfony は #include 仮想ディレクティブのみを管理します。

Caution

注意

Be careful with SSI, your website may fall victim to injections. Please read this OWASP article first!

SSI には注意してください。Web サイトがインジェクションの被害に遭う可能性があります。まず、この OWASP の記事をお読みください。

When the web server reads an SSI directive, it requests the given URI or gives directly from its cache. It repeats this process until there is no more SSI directives to handle. Then, it merges all responses into one and sends it to the client.

Web サーバーは、SSI ディレクティブを読み取るときに、指定された URI を要求するか、キャッシュから直接渡します。処理する SSI ディレクティブがなくなるまで、このプロセスが繰り返されます。次に、すべての応答を 1 つにマージしてクライアントに送信します。

Using SSI in Symfony

First, to use SSI, be sure to enable it in your application configuration:

まず、SSI を使用するには、アプリケーション構成で必ず有効にしてください。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
# config/packages/framework.yaml
framework:
    ssi: { enabled: true }

Suppose you have a page with private content like a Profile page and you want to cache a static GDPR content block. With SSI, you can add some expiration on this block and keep the page private:

プロフィール ページのようなプライベート コンテンツを含むページがあり、静的な GDPR コンテンツ ブロックをキャッシュしたいとします。 SSI を使用すると、このブロックに有効期限を追加して、ページをプライベートに保つことができます。
  • Attributes
    属性
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// src/Controller/ProfileController.php
namespace App\Controller;

use Symfony\Component\HttpKernel\Attribute\Cache;
// ...

class ProfileController extends AbstractController
{
    public function index(): Response
    {
        // by default, responses are private
        return $this->render('profile/index.html.twig');
    }

    #[Cache(smaxage: 600)]
    public function gdpr(): Response
    {
        return $this->render('profile/gdpr.html.twig');
    }
}

The profile index page has not public caching, but the GDPR block has 10 minutes of expiration. Let's include this block into the main one:

プロファイル インデックス ページにはパブリック キャッシュはありませんが、GDPR ブロックには 10 分の有効期限があります。このブロックをメインブロックに含めましょう:
1
2
3
4
5
6
7
{# templates/profile/index.html.twig #}

{# you can use a controller reference #}
{{ render_ssi(controller('App\\Controller\\ProfileController::gdpr')) }}

{# ... or a path (in server's SSI configuration is common to use relative paths instead of absolute URLs) #}
{{ render_ssi(path('profile_gdpr')) }}

The render_ssi twig helper will generate something like:

render_ssi twig ヘルパーは次のようなものを生成します:
1
<!--#include virtual="/_fragment?_hash=abcdef1234&_path=_controller=App\Controller\ProfileController::gdpr" -->

render_ssi ensures that SSI directive is generated only if the request has the header requirement like Surrogate-Capability: device="SSI/1.0" (normally given by the web server). Otherwise it will embed directly the sub-response.

render_ssi は、リクエストに Surrogate-Capability: device="SSI/1.0" (通常は Web サーバーによって指定される) のようなヘッダー要件がある場合にのみ、SSI ディレクティブが生成されるようにします。それ以外の場合は、サブレスポンスを直接埋め込みます。

Note

ノート

For more information about Symfony cache fragments, take a tour on the ESI documentation.

Symfony キャッシュ フラグメントの詳細については、ESI ドキュメントのツアーに参加してください。