Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Fluid Laravel Package

typo3fluid/fluid

TYPO3Fluid is a standalone PHP templating engine from TYPO3, providing the Fluid syntax for building secure, reusable templates with view helpers, layouts, partials, and caching. Use it in any PHP project without the full TYPO3 CMS stack.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup in Laravel

  1. Installation:

    composer require typo3fluid/fluid
    

    Fluid is dependency-agnostic but requires PHP 8.1+.

  2. Basic Rendering:

    use Fluid\Fluid\View\TemplateView;
    use Fluid\Fluid\Core\Parser\Syntax\TemplateParser;
    
    // Initialize parser and template view
    $parser = new TemplateParser();
    $templateView = new TemplateView();
    $templateView->setParser($parser);
    
    // Render a simple template
    $templateView->setTemplateSource('Hello {name}!');
    $templateView->assign('name', 'Laravel');
    echo $templateView->render();
    

    Output: Hello Laravel!

  3. First Use Case: Create a resources/views/fluid/hello.fluid.html file:

    <h1>{greeting}</h1>
    <p>Current time: {f:format.date(format: 'Y-m-d H:i:s')}</p>
    

    Render it in a Laravel controller:

    use Fluid\Fluid\View\TemplateView;
    use Fluid\Fluid\Core\Parser\Syntax\TemplateParser;
    
    public function showGreeting()
    {
        $parser = new TemplateParser();
        $templateView = new TemplateView();
        $templateView->setParser($parser);
        $templateView->setTemplatePathAndFilename(resource_path('views/fluid/hello.fluid.html'));
        $templateView->assignMultiple([
            'greeting' => 'Welcome to Fluid in Laravel',
            'date' => now(),
        ]);
        return response($templateView->render());
    }
    

Implementation Patterns

1. Template Organization

  • Partial Templates: Use <f:render partial="partialName" arguments="{...}"> to modularize templates. Example: resources/views/fluid/partials/alert.fluid.html

    <div class="alert {severity}">
        {message}
    </div>
    

    Render in parent template:

    <f:render partial="Alert" arguments="{severity: 'error', message: 'Something went wrong'}" />
    
  • Layouts: Define a base layout (resources/views/fluid/layouts/base.fluid.html):

    <!DOCTYPE html>
    <html>
        <head>
            <title>{title}</title>
        </head>
        <body>
            {content}
        </body>
    </html>
    

    Extend in child templates:

    <f:layout name="Base" />
    <f:section name="title">My Page</f:section>
    <f:section name="content">
        <h1>Hello, {name}!</h1>
    </f:section>
    

2. ViewHelpers Integration

  • Core ViewHelpers: Use built-in ViewHelpers like f:format.date, f:for, f:if, etc. Example:

    <f:for each="{users}" as="user">
        <li>{user.name} ({f:format.date(date: user.createdAt)})</li>
    </f:for>
    
  • Custom ViewHelpers: Extend AbstractViewHelper to create reusable components. Example: app/ViewHelpers/FormatCurrencyViewHelper.php

    namespace App\ViewHelpers;
    
    use Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
    use Fluid\Fluid\Core\Rendering\RenderingContextInterface;
    
    class FormatCurrencyViewHelper extends AbstractViewHelper
    {
        public function render(): string
        {
            $amount = $this->arguments['amount'] ?? 0;
            $currency = $this->arguments['currency'] ?? 'USD';
            return '$' . number_format($amount, 2) . ' ' . $currency;
        }
    }
    

    Register in config/fluid.php:

    'viewHelpers' => [
        'App\\ViewHelpers\\' => true,
    ],
    

    Use in template:

    <p>Price: {f:formatCurrency(amount: 1999.99, currency: 'EUR')}</p>
    

3. Dynamic Template Resolution

  • Template Paths: Configure multiple template paths in config/fluid.php:

    'templatePaths' => [
        resource_path('views/fluid'),
        base_path('resources/views/fluid/overrides'),
    ],
    

    Fluid resolves templates in order, supporting fallback chains (e.g., page.fluid.htmlpage.html).

  • Component-Based Rendering: Use the Annotations API (Fluid 5+) to auto-generate component listings. Example: app/Components/UserCard.php

    namespace App\Components;
    
    use Fluid\Fluid\Core\Component\AbstractComponent;
    
    #[Component('user-card')]
    class UserCard extends AbstractComponent
    {
        public function render(): string
        {
            return $this->renderTemplate('UserCard');
        }
    }
    

    Template: resources/views/fluid/Components/UserCard.fluid.html

    <div class="user-card">
        <h3>{user.name}</h3>
        <p>{user.email}</p>
    </div>
    

    Render in template:

    <f:component.name="user-card" arguments="{user: user}" />
    

4. Caching Strategies

  • Automatic Caching: Enable caching in config/fluid.php:

    'cache' => [
        'enabled' => true,
        'directory' => storage_path('framework/cache/fluid'),
    ],
    

    Warm up the cache during deployment:

    php artisan fluid:warmup
    

    Or manually:

    use Fluid\Fluid\Core\Cache\CacheFactory;
    use Fluid\Fluid\Core\Parser\Syntax\TemplateParser;
    
    $cacheFactory = new CacheFactory();
    $cache = $cacheFactory->create();
    $parser = new TemplateParser();
    $parser->setCache($cache);
    
  • Cache Invalidation: Clear cache when templates change:

    php artisan cache:clear
    

    Or programmatically:

    \Illuminate\Support\Facades\Cache::forget('fluid');
    

5. Integration with Laravel Blade

  • Hybrid Templates: Use Fluid for complex logic and Blade for simplicity where possible. Example: resources/views/fluid/partials/blade.fluid.html
    @if($showWelcome)
        <p>Welcome back, {user.name}!</p>
    @endif
    
    Note: Blade directives (@) are parsed by Laravel, not Fluid.

Gotchas and Tips

Pitfalls

  1. Variable Escaping:

    • Fluid auto-escapes output by default (XSS protection).
    • Use {variable} (escaped) vs. {variable.raw} (unescaped).
    • For trusted HTML, implement UnsafeHTML interface:
      $safeHtml = new \Fluid\Fluid\Core\Rendering\UnsafeHtmlString('<strong>Bold</strong>');
      
      Render in template:
      {safeHtml}
      
  2. Case Sensitivity in Template Names:

    • Fluid 5+ supports case-insensitive template resolution (e.g., home.fluid.html or Home.fluid.html).
    • Ensure consistency in your project (e.g., kebab-case for files).
  3. CDATA Syntax Collisions:

    • In <![CDATA[ ]]> sections, use {{{ ... }}} instead of { ... } to avoid conflicts with JavaScript/CSS.
    • Example:
      <script>
          <![CDATA[
              const name = "{{{ user.name }}}"; // Note triple braces
          ]]>
      </script>
      
  4. ViewHelper Argument Validation:

    • Fluid 5+ uses strict argument validation. Ensure your ViewHelpers define proper type hints:
      public function render(): string {
          $this->arguments['name']->validateNotEmptyString();
          return $this->arguments['name'];
      }
      
    • Common exceptions:
      • InvalidArgumentException for invalid types.
      • MissingArgumentException for required arguments.
  5. Template Path Priority:

    • Fluid resolves templates in the order defined in templatePaths. Overrides must be placed after the base path.
    • Example:
      'templatePaths' => [
          base_path('resources/views/fluid/base'), // Base templates
          base_path('resources/views/fluid/overrides'), // Overrides (higher priority)
      ],
      
  6. Caching Quirks:

    • Cache keys are based on template source + arguments. Changing a template requires cache invalidation.
    • Avoid dynamic template paths (e.g., resources/views/fluid/{dynamicFolder}/template.fluid.html) as they break caching.
  7. Deprecated Features:

    • `setChild
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport