承接 wabisoft/craft-bonsai-twig 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

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

wabisoft/craft-bonsai-twig

Composer 安装命令:

composer require wabisoft/craft-bonsai-twig

包简介

Internal use template helper

README 文档

README

Welcome to the Bonsai Twig Plugin README! This plugin is designed as a development-only tool to streamline your Twig templating experience by providing hierarchical template loading for various element types in Craft CMS 5.

Features

  • Hierarchical Template Loading: Automatically resolve templates for entries, categories, items, matrix blocks, and assets with intelligent fallback mechanisms
  • PHP 8.2 & Craft CMS 5 Optimized: Built with modern PHP features including null-safe operators and union types
  • Simple Debug Tools: Clean, focused debugging that shows template paths and resolution without performance overhead
  • Development-Focused: Designed specifically for development workflow - no production features or optimizations
  • Enhanced btPath() Function: Returns complete HTML output with styling, eliminating need for manual Twig wrapping
  • LLM Trace Comments: Opt-in, dev-only HTML comments mapping rendered DOM back to the winning template, consumable by AI agents reading page source
  • Zero Production Overhead: Debug features return empty strings in production mode

Function Reference

Each loader has its own doc with the full parameter list, resolution hierarchy, and a pure-Twig replacement if you ever remove the plugin:

Also: MIGRATION.md (v8 → v9 upgrade) · CHANGELOG.md

Requirements

  • PHP: 8.2.0 or higher
  • Craft CMS: 5.0.0 or higher

Getting Started

1. Install

The plugin ships inside the project as a Composer path repository:

// composer.json
{
    "repositories": [
        { "type": "path", "url": "_dev/plugins/craft-bonsai-twig" }
    ]
}
ddev composer require wabisoft/craft-bonsai-twig
ddev craft plugin/install bonsai-twig

2. Add your first template tree

Call a loader where you'd normally write an {% include %}:

{{ entryTemplates({ entry }) }}

Then create templates under templates/_entry/. Bonsai tries paths from most to least specific and renders the first one that exists:

templates/_entry/
├── blog/
│   ├── article/
│   │   └── my-post.twig    ← just this slug
│   ├── article.twig        ← this entry type
│   └── default.twig        ← anything in blog
└── default.twig            ← global fallback

Start with a single _entry/{section}/default.twig and add more specific templates only where a page needs to differ — no template calls change, resolution picks them up automatically.

The same pattern applies to the other trees: _matrix/, _category/, _item/, _asset/, _product/ — each with its own loader function (see Usage Guide).

3. See what's resolving

Add ?beastmode to any URL (or press Cmd+B) to see every path tried and which one won. For AI agents reading page source, enable LLM trace comments instead.

Template Resolution Strategy (v8.0)

By default, templates resolve section-first (entry/{section}/{type}/...). In v8.0, you can opt into type-first resolution (entry/{type}/{section}/...), aligning with Craft 5's standalone entry types.

Setting the Strategy

Three levels of configuration (highest to lowest precedence):

1. Per-template (highest priority):

{{ entryTemplates({ entry: entry, strategy: 'type' }) }}
{{ itemTemplates({ entry: item, strategy: 'type' }) }}

2. Config file:

// config/bonsai-twig.php
return [
    'strategy' => 'type', // default is 'section'
];

3. Control Panel:

Radio buttons in Settings > Bonsai Twig > Template Resolution Strategy.

If unset at all levels, defaults to 'section' — identical behavior to v7.

Path Resolution Comparison

For an entry with section blog and type article:

Priority Section-first (default) Type-first
1 _entry/blog/article/{slug} _entry/article/blog/{slug}
2 _entry/blog/article/_entry _entry/article/blog/_entry
3 _entry/blog/{slug} _entry/article/{slug}
4 _entry/blog/article _entry/article/blog
5 _entry/blog/default _entry/article/default
6 _entry/blog _entry/article
7 _entry/article _entry/blog
8 _entry/default _entry/default

Strategies can be mixed — set a global default, then override per template call or per section. Patterns in readme-entry.md and readme-item.md.

Which Loaders Support Strategy?

Loader Strategy support
entryTemplates() Yes
itemTemplates() Yes (item + ctx dimensions)
matrixTemplates() No (already type-centric)
categoryTemplates() No (legacy, no entry types)
assetTemplates() No (volume/folder based)

Usage Guide

Six loader functions, one pattern: pass the element, get the most specific template that exists. Each heading links to the full reference (all parameters, complete hierarchy).

Entry — entryTemplates()

{{ entryTemplates({ entry }) }}
{{ entryTemplates({ entry, style: 'featured', strategy: 'type' }) }}

Category — categoryTemplates()

{{ categoryTemplates({ entry: category }) }}

Item — itemTemplates()

For related/nested entries; style participates in path resolution.

{% for item in entry.relatedItems.all() %}
    {{ itemTemplates({ entry: item, style: 'compact' }) }}
{% endfor %}

Matrix — matrixTemplates()

Style-, handle-, context-, and position-aware. Pass loopIndex/loopLength to expose a loop variable inside block templates.

{% for block in entry.matrixField.all() %}
    {{ matrixTemplates({
        block: block,
        ctx: entry,
        loopIndex: loop.index0,
        loopLength: loop.length,
    }) }}
{% endfor %}

Asset — assetTemplates()

Resolves by volume → folder → filename.

{{ assetTemplates({ asset: image }) }}

Product — productTemplates()

{{ productTemplates({ product }) }}

Template Path Display — btPath()

Returns a self-styled HTML block listing every attempted path with the resolved one marked ✓. Call it anywhere in a template — no wrapping needed; returns an empty string in production.

{{ btPath() }}

{# Or inside an HTML comment for minimal visual impact #}
<!-- {{ btPath() }} -->

Debug Features

The plugin provides debugging tools that are only active in development mode (devMode = true).

Debug Mode

Keyboard Shortcut (Recommended)

Press Cmd+B (Mac) or Ctrl+B (Windows/Linux) to open the Beastmode options modal. This lets you select which template types to debug without manually editing the URL.

URL Parameter

Add ?beastmode to any URL to enable debug mode for all template types:

https://yoursite.test/some-page?beastmode

Or filter by specific types (comma-separated):

https://yoursite.test/some-page?beastmode=entry,matrix

Valid types: entry, category, item, matrix, asset, product, or all

Debug Information Display

When debug mode is active, you'll see clean debug output showing:

Template Resolution Information

  • Template Paths: All attempted template paths in priority order
  • Resolved Template: The template that was successfully loaded (marked with ✓)
  • Template Type: Context information (Entry, Matrix, Category, Item)

The debug output focuses on essential information without performance metrics or complex styling.

Every loader call gains the overlay automatically — no template changes needed.

LLM Trace Comments (v9.3)

When enabled, every Bonsai-resolved render is bracketed in machine-parseable HTML comments mapping the rendered DOM back to the winning template and its resolution context — the same map the beastmode overlay shows, but inline in the page source, consumable by an LLM/agent:

<!-- bonsai:start id="c4f91a2b-3" tpl="_entry/blog/default" type="entry" el="blogPost#64" section="blog" tried="_entry/blog/blogPost/my-post|_entry/blog/blogPost/_entry|_entry/blog/my-post|_entry/blog/blogPost" -->
…rendered template output…
<!-- bonsai:end id="c4f91a2b-3" -->

Pairs match on id (a per-page nonce + counter, so page content can't forge plausible pairs); nested loader calls yield nested pairs, so the comment tree mirrors the render tree. A page-level <!-- bonsai:trace v="1" nonce="…" --> marker is emitted whenever tracing is active — even on pages with no Bonsai renders. Comments carry paths, ids, and handles only — never field values.

The full attribute grammar lives in example.CLAUDE.md — the one file consuming agents read.

Enabling

Two independent conditions, both required:

emit == devMode === true AND llmMode === true

llmMode is the switch; devMode is the safety floor — trace comments never render in production, even with BONSAI_LLM_MODE=true in a production .env.

Staging caveat: tried enumerates your template tree and content-model handles in every page's source. Don't enable llmMode on internet-reachable staging servers that run devMode=true.

Enable via any of (precedence: env > config file > CP setting):

// config/bonsai-twig.php
return [
    'llmMode' => true,
];
# .env
BONSAI_LLM_MODE=true

Or toggle "LLM trace comments" in the plugin's CP settings.

Opting out (non-HTML contexts)

A wrapped template rendering into JSON-LD, <script>, <style>, <title>, an attribute value, or whitespace-sensitive output (<pre>) would be corrupted by an HTML comment:

{# Suppress wrapping for this render and everything it renders #}
{{ entryTemplates({ entry, bonsaiTrace: false }) }}

Labelling static components

Trace comments mark dynamic resolutions only — plain {% include %}s are followed by reading source. For components included through dynamic names (or just for convenience), templates can self-label using bonsaiTraceEnabled(), which gates on the same devMode + llmMode switch:

{# Inline, inside any component #}
{% if bonsaiTraceEnabled() %}<!-- cmp: {{ _self }} -->{% endif %}
{# Or as a shared macro, e.g. templates/_macros/dev.twig. This form calls the
   plugin instance instead of the Twig function, so templates keep compiling
   if the plugin is ever removed (an undefined Twig function is a
   compile-time error). Note: _self inside a macro names the macro's own
   file, so the caller must pass it. #}
{% macro trace(tpl) -%}
    {%- set bonsai = craft.app.plugins.getPlugin('bonsai-twig') -%}
    {%- if bonsai and bonsai.traceEnabled() %}<!-- cmp: {{ tpl }} -->{% endif -%}
{%- endmacro %}

{# In a component: #}
{% import '_macros/dev' as dev %}
{{ dev.trace(_self) }}

Agent consumption recipe

example.CLAUDE.md is a ready-to-append snippet for a consumer project's CLAUDE.md — the comment grammar, how to fetch raw source, nesting semantics, and how to read a fallthrough:

cat vendor/wabisoft/craft-bonsai-twig/example.CLAUDE.md >> CLAUDE.md

Integration with Craft 5

Unified Element Model

In Craft CMS 5, categories are now entries, which simplifies template handling. The plugin automatically handles this unification while maintaining backward compatibility.

Integration with Craft 5 render()

The plugin works alongside Craft 5's built-in render() method. While render() looks for templates in _partials/{elementType}/{elementName}.twig, Bonsai Twig provides more sophisticated hierarchical resolution.

Craft 5 render():

{{ entry.render() }}  {# Looks for _partials/entry/blog.twig #}

Bonsai Twig:

{{ entryTemplates({ entry }) }}  {# Checks multiple hierarchical paths #}

You can use both approaches as needed - render() for simple cases and Bonsai Twig for complex hierarchical template systems.

Development-Only Focus

This plugin is designed specifically as a development tool and includes:

Simplified Architecture

  • No Caching: Templates change frequently in development, so no caching overhead
  • Direct File System Checks: Simple template existence checking without optimization layers
  • Minimal Dependencies: Only essential services for template loading
  • Straightforward Logic: Easy to understand and maintain codebase

Basic Security

  • Path Sanitization: Basic path cleaning to prevent directory traversal
  • Input Validation: Simple parameter type checking
  • Safe Property Access: Uses null-safe operators for element properties

Migration

Upgrading from v8? The v9 breaking changes (underscore path prefixes, plugin handle, config file rename) are covered in MIGRATION.md.

Troubleshooting

Debug Mode Not Working

  1. Ensure devMode = true in your Craft configuration
  2. Check that you're using the correct URL parameter: ?beastmode
  3. Verify the plugin is installed and enabled

Templates Not Found

  1. Use debug mode to see which paths are being checked: ?beastmode
  2. Verify your template directory structure matches the expected hierarchy
  3. Check file permissions on template directories

Template Resolution Issues

  1. Use debug mode to see which paths are being checked: ?beastmode or ?beastmode=entry,matrix
  2. Use the enhanced btPath() function in your templates to see resolution info
  3. Consider simplifying complex template hierarchies

Changelog

See CHANGELOG.md.

wabisoft/craft-bonsai-twig 适用场景与选型建议

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

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

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

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

BUG 修复 & 性能优化

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

项目外包 & 长期维护

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

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

统计信息

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

GitHub 信息

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

其他信息

  • 授权协议: Unknown
  • 更新时间: 2023-06-13