lliure/twig-container 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

lliure/twig-container

Composer 安装命令:

composer require lliure/twig-container

包简介

Twig extension for container-based template composition with additive content injection

README 文档

README

Latest Version PHP Version License

Vue-like slots for Twig. Container-based template composition with additive content injection.

Perfect for injecting scripts, styles, and components from child templates into parent layouts.

Why This Library?

Twig's native {% block %} is substitutive - child blocks replace parent blocks. But sometimes you need additive composition:

{# ❌ Problem: Each component overwrites the scripts block #}
{% block scripts %}
    <script src="datepicker.js"></script>
{% endblock %}

{# ✅ Solution: Components ADD to the container #}
{% inject 'scripts' %}
    <script src="datepicker.js"></script>
{% endinject %}

Features

FeatureDescription
ContainersNamed areas that accumulate content
InjectAdd content from anywhere (before or after the container)
UniquePrevent duplicate injections (CSS/JS)
PackageReusable components with isolated context
content()Mix original content with injections

Comparison with Alternatives

Featuretwig-stacklliure/twig-container
Push/Inject
Prevent duplicatespushonceunique with auto or manual ID
Mix original + injected{{ content() }}
Reusable components{% package %}
Dynamic paths{% package path ~ '.twig' %}

Installation

composer require lliure/twig-container

Quick Start

use TwigContainer\Container;
use TwigContainer\ContainerRuntime;

// Add extension
$twig->addExtension(new Container());

// Add runtime loader
$twig->addRuntimeLoader(new class implements \Twig\RuntimeLoader\RuntimeLoaderInterface {
    private ?ContainerRuntime $runtime = null;
    public function load(string $class): ?object {
        if ($class === ContainerRuntime::class) {
            return $this->runtime ??= new ContainerRuntime();
        }
        return null;
    }
});

// Render with post-processing
$output = $twig->render('template.twig');
$runtime = $twig->getRuntime(ContainerRuntime::class);
echo $runtime->processPlaceholders($output);

Usage

Container

Define a named area:

{% container 'scripts' %}
    <script src="base.js"></script>
    {{ content() }}
{% endcontainer %}
  • {{ content() }} marks where injections appear
  • Without content(): injections replace original content
  • Without injections: shows original content

Inject

Add content to a container:

{% inject 'scripts' %}
    <script src="page.js"></script>
{% endinject %}

Works before or after the container (placeholder magic).

Unique Inject

Prevent duplicates (great for CSS/JS libraries):

{# Auto-unique based on file:line #}
{% inject 'styles' unique %}
    <link rel="stylesheet" href="datepicker.css">
{% endinject %}

{# Manual ID for cross-file deduplication #}
{% inject 'styles' unique 'datepicker-css' %}
    <link rel="stylesheet" href="datepicker.css">
{% endinject %}

Package

Include reusable components with isolated context:

{% package 'components/datepicker.twig' with {name: 'birthday', format: 'd/m/Y'} %}

Supports dynamic paths:

{% for field in fields %}
    {% package 'components/' ~ field.type ~ '.twig' with field.config %}
{% endfor %}

Real-World Example

The Problem

You have a datepicker component used multiple times. You need:

  • CSS loaded once
  • JS initialization for each instance
  • Everything in the right place (head/footer)

The Solution

components/datepicker.twig:

<input type="text" name="{{ name }}" class="datepicker" data-format="{{ format }}">

{# CSS - loads once per page #}
{% inject 'styles' unique 'datepicker' %}
    <link rel="stylesheet" href="datepicker.css">
{% endinject %}

{# JS - one per instance #}
{% inject 'scripts' %}
    <script>initDatepicker('{{ name }}', '{{ format }}');</script>
{% endinject %}

layout.twig:

<!DOCTYPE html>
<html>
<head>
    {% container 'styles' %}{{ content() }}{% endcontainer %}
</head>
<body>
    {% block content %}{% endblock %}

    {% container 'scripts' %}
        <script src="app.js"></script>
        {{ content() }}
    {% endcontainer %}
</body>
</html>

form.twig:

{% extends 'layout.twig' %}

{% block content %}
    <form>
        {% package 'components/datepicker.twig' with {name: 'start', format: 'd/m/Y'} %}
        {% package 'components/datepicker.twig' with {name: 'end', format: 'd/m/Y'} %}
    </form>
{% endblock %}

Output:

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="datepicker.css">
</head>
<body>
    <form>
        <input type="text" name="start" class="datepicker" data-format="d/m/Y">
        <input type="text" name="end" class="datepicker" data-format="d/m/Y">
    </form>

    <script src="app.js"></script>
    <script>initDatepicker('start', 'd/m/Y');</script>
    <script>initDatepicker('end', 'd/m/Y');</script>
</body>
</html>

CSS loads once, scripts load per instance.

Running Tests

php tests/run.php              # Visual output
php tests/run.php --validate   # Exit code for CI

License

MIT - see LICENSE

Contributing

Issues and PRs welcome at Bitbucket.

lliure/twig-container 适用场景与选型建议

lliure/twig-container 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 0 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 03 月 23 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「container」 「package」 「twig」 「template」 「composition」 「inject」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 lliure/twig-container 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 lliure/twig-container 我们能提供哪些服务?
定制开发 / 二次开发

基于 lliure/twig-container 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 33
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-03-23