PHPackages                             wabisoft/craft-bonsai-twig - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Templating &amp; Views](/categories/templating)
4. /
5. wabisoft/craft-bonsai-twig

ActiveCraft-plugin[Templating &amp; Views](/categories/templating)

wabisoft/craft-bonsai-twig
==========================

Internal use template helper

9.2.6(1mo ago)01.3k↓82.7%PHPPHP &gt;=8.2.0

Since Jun 13Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/wabi-soft/craft-bonsai-twig)[ Packagist](https://packagist.org/packages/wabisoft/craft-bonsai-twig)[ RSS](/packages/wabisoft-craft-bonsai-twig/feed)WikiDiscussions main Synced 2d ago

READMEChangelogDependencies (16)Versions (64)Used By (0)

Bonsai Twig Plugin
==================

[](#bonsai-twig-plugin)

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
--------

[](#features)

- **Hierarchical Template Loading**: Automatically resolve templates for entries, categories, items, matrix blocks, and assets with intelligent fallback mechanisms
- **PHP 8.2 &amp; 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
- **Zero Production Overhead**: Debug features return empty strings in production mode

Pure Twig Equivalents
---------------------

[](#pure-twig-equivalents)

If you need to remove the plugin, see these guides for native Twig replacements:

- [Entry Templates](readme-entry.md) - `entryTemplates()`
- [Category Templates](readme-category.md) - `categoryTemplates()`
- [Item Templates](readme-item.md) - `itemTemplates()`
- [Matrix Templates](readme-matrix.md) - `matrixTemplates()`
- [Asset Templates](readme-asset.md) - `assetTemplates()`
- [Product Templates](readme-product.md) - `productTemplates()`

Requirements
------------

[](#requirements)

- **PHP**: 8.2.0 or higher
- **Craft CMS**: 5.0.0 or higher

Template Resolution Strategy (v8.0)
-----------------------------------

[](#template-resolution-strategy-v80)

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

[](#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'
];
```

**Upgrading from v8?** To keep your existing template directories working without renaming them:

```
// config/bonsai-twig.php
return [
    'paths' => [
        'entry'    => 'entry',
        'item'     => 'item',
        'category' => 'category',
        'matrix'   => 'matrix',
        'asset'    => 'asset',
        'product'  => 'product',
    ],
];
```

**3. Control Panel:**

Radio buttons in Settings &gt; Bonsai Twig &gt; Template Resolution Strategy.

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

### Path Resolution Comparison

[](#path-resolution-comparison)

For an entry with section `blog` and type `article`:

PrioritySection-first (default)Type-first1`_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`### Mixed Strategies

[](#mixed-strategies)

You can use both strategies in the same project. Set a global default via config, then override per-template:

```
{# Most templates use global strategy (e.g., 'type') #}
{{ entryTemplates({ entry: entry }) }}

{# This one overrides to section-first #}
{{ entryTemplates({ entry: entry, strategy: 'section' }) }}
```

#### Per-Section Strategy

[](#per-section-strategy)

Use a conditional to pick the strategy based on the current section:

```
{# Sections with shared entry types use type-first; the rest use section-first #}
{% set strategy = entry.section.handle in ['blog', 'resources'] ? 'type' : 'section' %}
{{ entryTemplates({ entry: entry, strategy: strategy }) }}
```

The same pattern works with `itemTemplates()`:

```
{% set strategy = item.section.handle in ['blog', 'resources'] ? 'type' : 'section' %}
{{ itemTemplates({ entry: item, strategy: strategy }) }}
```

### Which Loaders Support Strategy?

[](#which-loaders-support-strategy)

LoaderStrategy 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
-----------

[](#usage-guide)

### Core Template Functions

[](#core-template-functions)

The plugin provides five main Twig functions for hierarchical template loading:

#### 1. Entry Templates

[](#1-entry-templates)

```
{{ entryTemplates({ entry }) }}
```

**Description**: Loads templates for entry elements with intelligent hierarchy resolution.

**Parameters**:

- `entry` (Entry): The entry element to render
- `path` (string, optional): Custom template path override
- `strategy` (string, optional): `'section'` (default) or `'type'` for type-first resolution
- `style` (string, optional): Style variant (forwarded to the template; does not alter Entry path resolution)
- `context` (Element, optional): Additional context element
- `baseSite` (string, optional): Base site handle for multi-site setups
- `variables` (array, optional): Additional variables to pass to the template **Example**:

```
{# Basic usage #}
{{ entryTemplates({ entry }) }}

{# With custom path and style #}
{{ entryTemplates({
    entry: entry,
    path: 'custom/path',
    style: 'featured'
}) }}

{# With type-first strategy #}
{{ entryTemplates({
    entry: entry,
    strategy: 'type'
}) }}

{# With additional context #}
{{ entryTemplates({
    entry: entry,
    context: parentEntry,
    variables: { customVar: 'value' }
}) }}
```

#### 2. Category Templates

[](#2-category-templates)

```
{{ categoryTemplates({ entry }) }}
```

**Description**: Loads templates for category elements (in Craft 5, categories are entries).

**Parameters**: Same as `entryTemplates`

**Example**:

```
{# Basic category rendering #}
{{ categoryTemplates({ entry: category }) }}

{# Category with style variant #}
{{ categoryTemplates({
    entry: category,
    style: 'card'
}) }}
```

#### 3. Item Templates

[](#3-item-templates)

```
{{ itemTemplates({ entry }) }}
```

**Description**: Specialized template loading for nested entry relationships and complex hierarchies.

**Parameters**: Same as `entryTemplates`

**Example**:

```
{# Render related items #}
{% for item in entry.relatedItems.all() %}
    {{ itemTemplates({ entry: item }) }}
{% endfor %}

{# Item with context awareness #}
{{ itemTemplates({
    entry: item,
    context: parentEntry,
    style: 'compact'
}) }}

{# Item with type-first strategy #}
{{ itemTemplates({
    entry: item,
    strategy: 'type'
}) }}
```

#### 4. Matrix Templates

[](#4-matrix-templates)

```
{{ matrixTemplates({ block }) }}
```

**Description**: Advanced template loading for Matrix blocks with style and context awareness.

**Parameters**:

- `block` (MatrixBlock): The matrix block to render
- `style` (string, optional): Style variant for the block
- `ctx` or `context` (Element, optional): Parent context element
- `loopIndex` (int, optional): Current loop iteration (0-indexed) for Twig loop variable
- `loopLength` (int, optional): Total number of items in loop for Twig loop variable
- `variables` (array, optional): Additional variables to pass to the template
- `next` (string, optional): Next block type for navigation
- `prev` (string, optional): Previous block type for navigation
- `isFirst` (bool, optional): Whether this is the first block
- `entry` (Entry, optional): Parent entry element
- `variables` (array, optional): Additional template variables

**Basic Example**:

```
{# Simple matrix block rendering #}
{% for block in entry.matrixField.all() %}
    {{ matrixTemplates({ block: block }) }}
{% endfor %}
```

**Advanced Example**:

```
{# Advanced matrix with full context and loop variables #}
{% if entry.matrixField|length %}
    {% set style = style ?? null %}
    {% for block in entry.matrixField.all() %}
        {{ matrixTemplates({
            block: block,
            style: style,
            loopIndex: loop.index0,    {# Pass current iteration (0-indexed) #}
            loopLength: loop.length,   {# Pass total number of blocks #}
            ctx: entry,
            next: block.next.type ?? false,
            prev: block.prev.type ?? false,
            isFirst: loop.first,
            context: context|default('basic'),
            entry: entry,
            variables: {
                customData: customValue,
                sectionHandle: entry.section.handle,
                blockPosition: loop.index,
                totalBlocks: loop.length
            }
        }) }}
    {% endfor %}
{% endif %}
```

**Variables Parameter**:

You can pass additional variables using either approach:

```
{# Approach 1: Direct parameters (backward compatible) #}
{{ matrixTemplates({
    block: block,
    customData: 'some value',
    sectionHandle: entry.section.handle
}) }}

{# Approach 2: Using variables parameter (recommended) #}
{{ matrixTemplates({
    block: block,
    loopIndex: loop.index0,
    loopLength: loop.length,
    variables: {
        customData: 'some value',
        sectionHandle: entry.section.handle,
        blockPosition: loop.index
    }
}) }}
```

Both approaches make the variables available in your matrix template. The `variables` parameter is useful for organizing custom data separately from system parameters.

#### 5. Asset Templates

[](#5-asset-templates)

```
{{ assetTemplates({ asset }) }}
```

**Description**: Loads templates for Craft asset elements with intelligent hierarchy based on volume, folder, and filename.

**Parameters**:

- `asset` (Asset): The asset element to render
- `path` (string, optional): Custom template path override (defaults to 'asset')
- `baseSite` (string, optional): Base site handle for multi-site setups

**Template Hierarchy**:

The asset loader checks for templates in this order:

1. `asset/{volume}/{folder}/{filename}` - Most specific match for a particular file
2. `asset/{volume}/{filename}` - For assets in root of volume (no folder)
3. `asset/{volume}/{folder}/default` - Default template for a specific folder
4. `asset/{volume}/default` - Default template for the volume
5. `asset/{volume}` - Volume-level template
6. `asset/default` - Global fallback

**Example Usage**:

```
{# Basic asset rendering #}
{{ assetTemplates({ asset: image }) }}

{# Render images in a gallery #}
{% for image in entry.gallery.all() %}
    {{ assetTemplates({ asset: image }) }}
{% endfor %}

{# Custom path #}
{{ assetTemplates({
    asset: document,
    path: 'downloads'
}) }}

{# Multi-site support #}
{{ assetTemplates({
    asset: image,
    baseSite: 'fr'
}) }}
```

**Example Template Structure**:

For an asset with volume `images`, folder `products/featured`, filename `hero.jpg`:

```
templates/
  asset/
    images/
      products/
        featured/
          hero.twig           ← Matches specific file
          default.twig        ← Folder fallback
      default.twig            ← Volume fallback
    default.twig              ← Global fallback

```

**Use Cases**:

- Custom rendering for different asset types (images, videos, PDFs)
- Volume-specific templates (e.g., different rendering for "documents" vs "images")
- Folder-based organization (e.g., "products" vs "blog" assets)
- File-specific templates for important assets

### 6. Enhanced Template Path Display (`btPath()`)

[](#6-enhanced-template-path-display-btpath)

The `btPath()` function has been enhanced to provide complete HTML output with styling, eliminating the need for manual Twig wrapping. This is particularly useful for item and matrix templates where you need to quickly identify which template is being used.

**Key Features:**

- **Complete HTML Output**: Returns formatted HTML with styling instead of plain text
- **Automatic Context Detection**: Shows appropriate template type (Matrix, Entry, Category, Item)
- **Zero Production Overhead**: Returns empty string in production mode
- **No Manual Wrapping**: No need for conditional blocks or manual HTML

#### Enhanced Usage Examples

[](#enhanced-usage-examples)

##### Simple Usage (New - Recommended)

[](#simple-usage-new---recommended)

Just call the function directly - it returns complete HTML:

```
{{ btPath() }}
```

This automatically outputs styled HTML like:

```

#bt-debug-abc123 {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 12px;
  background: #1e1e1e;
  color: #d4d4d4;
  border: 1px solid #454545;
  border-radius: 6px;
  padding: 12px;
  margin: 8px 0;
}
/* Additional scoped styles... */

Matrix Block Template

  → matrix/textBlock--hero.twig
  ✓ matrix/textBlock.twig
  → matrix/default.twig

```

The output includes:

- A unique `id` attribute to scope CSS and avoid conflicts
- Inline `` block with scoped selectors
- Dark theme styling for developer-friendly display
- Visual indicators: ✓ for resolved template, → for attempts

##### Legacy Usage (Manual Wrapping)

[](#legacy-usage-manual-wrapping)

You can still manually wrap the output if needed, though it's no longer necessary:

```
{% if btPath() %}

        {{ btPath() }}

{% endif %}
```

**Note**: The legacy `` output format from earlier versions is no longer used. The current implementation uses the `` wrapper with inline styles shown above.

##### HTML Comment Usage

[](#html-comment-usage)

For minimal visual impact:

```

```

#### Output Features

[](#output-features)

The enhanced `btPath()` automatically includes:

- **Template Type Context**: Shows "Matrix Block Template", "Entry Template", etc.
- **Resolved Template Marking**: The found template is marked with ✓
- **Clean Styling**: Simple, unobtrusive CSS styling
- **Attempted Paths**: All paths checked during resolution

#### Production Mode Behavior

[](#production-mode-behavior)

In production mode (`devMode = false`), `btPath()` returns an empty string with zero overhead:

```
{{ btPath() }}
```

Debug Features
--------------

[](#debug-features)

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

### Debug Mode

[](#debug-mode)

#### Keyboard Shortcut (Recommended)

[](#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

[](#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

[](#debug-information-display)

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

#### Template Resolution Information

[](#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.

### Debug Examples

[](#debug-examples)

#### Entry Debug Example

[](#entry-debug-example)

```
{# Entry template with debug capability #}
{# Add ?beastmode to URL to see template resolution info #}
{{ entryTemplates({ entry }) }}
```

#### Category Debug Example

[](#category-debug-example)

```
{# Category template with debug capability #}
{# Add ?beastmode to URL to see template resolution info #}
{{ categoryTemplates({ entry: category }) }}
```

#### Item Debug Example

[](#item-debug-example)

```
{# Item template with debug capability #}
{# Add ?beastmode to URL to see template resolution info #}
{{ itemTemplates({ entry: item }) }}
```

#### Matrix Debug Example

[](#matrix-debug-example)

```
{# Matrix template with debug capability #}
{# Add ?beastmode to URL to see template resolution info #}
{% for block in entry.matrixField.all() %}
    {{ matrixTemplates({ block: block }) }}
{% endfor %}
```

#### Enhanced btPath() Debug Example

[](#enhanced-btpath-debug-example)

```
{# Enhanced btPath() - returns complete HTML output #}
{{ btPath() }}

{# Or use in HTML comments for minimal impact #}

```

### Suggested Minimum Usage

[](#suggested-minimum-usage)

For the most common use cases, here are the recommended minimal implementations:

#### Basic Matrix Templates (Craft 4→5 Migration)

[](#basic-matrix-templates-craft-45-migration)

```
{# Replaces the old matrix include pattern #}
{% for block in matrix.all() %}
    {{ matrixTemplates({
        block: block,
        handle: handle ?? null,
        style: style ?? null
    }) }}
{% endfor %}
```

This automatically resolves templates in this order:

1. `matrix/handle/{handle}/{blockType}.twig` (if handle provided)
2. `matrix/style/{style}/{blockType}.twig` (if style provided)
3. `matrix/{blockType}.twig` (main template)
4. `matrix/default.twig` (fallback)

#### Simple Entry Templates

[](#simple-entry-templates)

```
{# Basic entry rendering #}
{{ entryTemplates({ entry: entry }) }}

{# Entry with style variant #}
{{ entryTemplates({ entry: entry, style: 'featured' }) }}
```

#### Basic Category Templates

[](#basic-category-templates)

```
{# Simple category rendering #}
{{ categoryTemplates({ entry: category }) }}
```

#### Basic Item Templates

[](#basic-item-templates)

```
{# For related entries or nested content #}
{% for item in entry.relatedItems.all() %}
    {{ itemTemplates({ entry: item }) }}
{% endfor %}
```

Template Resolution

### How Template Resolution Works

[](#how-template-resolution-works)

The plugin uses intelligent hierarchical template resolution that checks multiple paths in priority order:

1. **Type-Specific Templates**: Templates based on element type and handle (e.g., `entry/blog/article`)
2. **Style Variants**: Style-based paths for items and matrix blocks (e.g., `item/{section}/{style}`, `matrix/style/{style}/{blockType}`)
3. **Fallback Templates**: Generic templates (e.g., `entry/default.twig`)

### Template Path Examples

[](#template-path-examples)

For an entry with section handle `blog` and type handle `article`:

```
# Checked in this order:
_entry/blog/article/{slug}
_entry/blog/article/_entry
_entry/blog/{slug}
_entry/blog/article
_entry/blog/default
_entry/blog
_entry/article
_entry/default

```

Note: The `style` parameter is passed to the template as a variable but does not change the entry path resolution. For style-aware path resolution, use `itemTemplates()` or `matrixTemplates()` instead.

### Matrix Block Resolution

[](#matrix-block-resolution)

Matrix blocks have style-aware path resolution:

```
# For a matrix block of type 'textBlock' with style 'hero':
_matrix/style/hero/textBlock
_matrix/textBlock
_matrix/default

```

Additional context-aware paths are available when using `ctx`, `handle`, or position parameters.

Integration with Craft 5
------------------------

[](#integration-with-craft-5)

### Unified Element Model

[](#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()`

[](#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
----------------------

[](#development-only-focus)

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

### Simplified Architecture

[](#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

[](#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 Guide
---------------

[](#migration-guide)

### Upgrading from Previous Versions

[](#upgrading-from-previous-versions)

The plugin maintains full backward compatibility, but you can take advantage of new features:

#### Enhanced Debug Parameters

[](#enhanced-debug-parameters)

**Old way:**

```
?showEntryPath=true&showEntryHierarchy=true

```

**New way (recommended):**

```
?beastmode
?beastmode=entry
?beastmode=entry,matrix

```

Or use the keyboard shortcut: **Cmd+B** / **Ctrl+B**

#### Template Function Signatures

[](#template-function-signatures)

All existing function signatures remain unchanged:

```
{# These continue to work exactly as before #}
{{ entryTemplates({ entry }) }}
{{ categoryTemplates({ entry }) }}
{{ itemTemplates({ entry }) }}
{{ matrixTemplates({ block }) }}
```

#### New Optional Parameters

[](#new-optional-parameters)

You can now use additional parameters for enhanced functionality:

```
{# New optional parameters #}
{{ entryTemplates({
    entry: entry,
    style: 'featured',        # New: style variants
    context: parentEntry,     # New: context awareness
    variables: { key: value } # New: additional variables
}) }}
```

### Simplified Implementation

[](#simplified-implementation)

The simplified version focuses on reliability and maintainability:

- **Straightforward Logic**: Simple template resolution without complex optimization
- **Reduced Complexity**: Fewer moving parts means fewer potential issues
- **Enhanced Debug Experience**: Improved btPath() function with complete HTML output
- **Zero Production Overhead**: Debug features automatically disabled in production

### PHP 8.2 Features

[](#php-82-features)

The plugin leverages essential modern PHP features:

- **Null-safe operators** for safer property access
- **Union types** for flexible parameter handling
- **Enums** for type-safe constants

Troubleshooting
---------------

[](#troubleshooting)

### Debug Mode Not Working

[](#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

[](#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

[](#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

Support
-------

[](#support)

For issues, feature requests, or questions:

1. Check the debug information using `?beastmode`
2. Use `{{ btPath() }}` in your templates to see resolution hierarchy
3. Verify your template structure matches the expected patterns
4. Check Craft and PHP version compatibility

Changelog
---------

[](#changelog)

### Version 8.0.0

[](#version-800)

- **Type-first template resolution strategy** — opt-in `strategy: 'type'` parameter for EntryLoader and ItemLoader
- Three-level configuration: per-template, config file, or CP settings
- Strategy displayed in beastmode overlay and `btPath()` debug output
- Version bump to 8.0.0 (no breaking changes when strategy is unset)

### Version 6.4.0

[](#version-640)

- Full Craft CMS 5 compatibility
- Simplified architecture focused on development workflow
- Enhanced btPath() function with complete HTML output
- Removed performance monitoring and caching complexity
- Streamlined debug tools for essential information only
- Development-only tool focus with zero production overhead

###  Health Score

50

—

FairBetter than 95% of packages

Maintenance88

Actively maintained with recent releases

Popularity18

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity71

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~18 days

Recently: every ~0 days

Total

59

Last Release

59d ago

Major Versions

v4.x-dev → 6.0.22024-08-05

v5.x-dev → 6.0.32024-11-07

6.4.0 → 7.0.02025-09-10

v6.x-dev → 8.0.02026-03-12

v8.x-dev → 9.0.02026-04-09

PHP version history (2 changes)0.0.1PHP &gt;=8.0.2

6.0.2PHP &gt;=8.2.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/40344699?v=4)[Wabisoft](/maintainers/wabisoft)[@wabisoft](https://github.com/wabisoft)

---

Top Contributors

[![dustinwalker](https://avatars.githubusercontent.com/u/360177?v=4)](https://github.com/dustinwalker "dustinwalker (136 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/wabisoft-craft-bonsai-twig/health.svg)

```
[![Health](https://phpackages.com/badges/wabisoft-craft-bonsai-twig/health.svg)](https://phpackages.com/packages/wabisoft-craft-bonsai-twig)
```

###  Alternatives

[verbb/vizy

A flexible visual editor field for Craft.

4250.4k](/packages/verbb-vizy)[verbb/hyper

A user-friendly links field for Craft.

24147.8k12](/packages/verbb-hyper)[verbb/footnotes

Adds a footnotes feature to CKEditor fields and Twig templates.

213.6k](/packages/verbb-footnotes)[froala/craft-froala-wysiwyg

Craft 3 CMS plugin for Froala WYSIWYG HTML Rich Text Editor.

1719.1k](/packages/froala-craft-froala-wysiwyg)[vierbeuter/craft-footnotes

Adds a footnotes feature to CKEditor fields and Twig templates.

212.7k](/packages/vierbeuter-craft-footnotes)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
