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

Renderer Laravel Package

derafu/renderer

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the Package:

    composer require derafu/renderer derafu/twig
    

    Ensure your composer.json specifies PHP 8.5+:

    "require": {
        "php": "^8.5",
        "derafu/renderer": "^1.0",
        "derafu/twig": "^1.0"
    }
    
  2. Publish Configuration:

    php artisan vendor:publish --provider="Derafu\Renderer\RendererServiceProvider" --tag="config"
    

    This creates config/renderer.php with default settings.

  3. Register the Service Provider: Add to config/app.php:

    'providers' => [
        // ...
        Derafu\Renderer\RendererServiceProvider::class,
    ],
    
  4. First Render: Create a Twig template at resources/views/hello.twig:

    <h1>Hello, {{ name }}!</h1>
    

    Render it in a controller:

    use Derafu\Renderer\Facades\Renderer;
    
    public function show()
    {
        return Renderer::render('hello', ['name' => 'Laravel']);
    }
    
  5. First Use Case: Use the renderer for non-Blade templates (e.g., PDFs, Markdown emails):

    // PDF example (requires mPDF)
    $pdfContent = Renderer::render('invoice.pdf.twig', ['user' => $user]);
    $pdf = new \Mpdf\Mpdf();
    $pdf->WriteHTML($pdfContent);
    $pdf->Output('invoice.pdf', 'D');
    

Implementation Patterns

Unified Rendering Workflow

  1. Template Organization: Store templates in resources/views/ with extensions indicating format:

    • .twig → Twig (default)
    • .md → Markdown (requires derafu/markdown)
    • .pdf.twig → PDF-ready Twig (processed by mPDF)
  2. Data Passing: Pass data as associative arrays (supports nested structures):

    $data = [
        'user' => $user,
        'items' => $order->items,
        'config' => config('app.settings'),
    ];
    $output = Renderer::render('template.twig', $data);
    
  3. Format-Specific Patterns:

    • PDFs: Use Twig templates with CSS/HTML for layout, then pipe to mPDF:
      $pdf = Renderer::renderToPdf('invoice.twig', ['data' => $data]);
      
    • Markdown: Render to Markdown and convert to HTML:
      $markdown = Renderer::render('email.md', ['data' => $data]);
      $html = \Michelf\Markdown::defaultTransform($markdown);
      
  4. Integration with Laravel:

    • Views: Replace view('name') with Renderer::render('name.twig') for Twig templates.
    • Responses: Return rendered content directly:
      return response(Renderer::render('email.md', $data), 200, ['Content-Type' => 'text/markdown']);
      
    • Mailables: Use in build() method:
      public function build()
      {
          $body = Renderer::render('emails.welcome.md', ['user' => $this->user]);
          return $this->markdown('emails.welcome')->with([
              'body' => $body,
          ]);
      }
      
  5. Caching: Leverage Laravel’s cache for Twig templates:

    Renderer::render('template.twig', $data, [
        'cache' => true,
        'cache_key' => 'template_' . md5(serialize($data)),
    ]);
    
  6. Error Handling: Wrap renders in try-catch for graceful degradation:

    try {
        $output = Renderer::render('template.twig', $data);
    } catch (\Derafu\Renderer\Exceptions\TemplateNotFoundException $e) {
        return response('Template not found', 500);
    }
    

Laravel-Specific Patterns

  1. Service Provider Customization: Extend the default provider to add engines or modify behavior:

    // app/Providers/RendererServiceProvider.php
    public function register()
    {
        $this->app->singleton('renderer', function ($app) {
            $renderer = new \Derafu\Renderer\Renderer([
                'twig' => new \Derafu\Twig\TwigEngine($app['path.base']),
                'blade' => $app['view'], // Optional: Fallback to Blade
            ]);
            $renderer->addEngine('md', new \Derafu\Markdown\MarkdownEngine());
            return $renderer;
        });
    }
    
  2. Facade Aliases: Add custom aliases in config/app.php:

    'aliases' => [
        // ...
        'Renderer' => \Derafu\Renderer\Facades\Renderer::class,
        'PdfRenderer' => \Derafu\Renderer\Facades\PdfRenderer::class, // Custom facade
    ],
    
  3. Artisan Commands: Create a custom command to validate templates:

    php artisan renderer:validate resources/views
    
  4. Testing: Use Laravel’s testing helpers with the renderer:

    public function testRenderer()
    {
        $this->app->make('renderer')->shouldReceive('render')
            ->once()
            ->with('template.twig', ['data' => 'test'])
            ->andReturn('<html>...</html>');
    }
    
  5. Livewire/Alpine Integration: For Twig templates used with Livewire, ensure Alpine.js/CDN inclusion:

    {# resources/views/hello.twig #}
    @extends('layouts.app')
    @section('scripts')
        @vite(['resources/js/app.js'])
        <script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
    @endsection
    

Gotchas and Tips

Pitfalls

  1. Twig vs. Blade Syntax:

    • Gotcha: Twig uses {{ }} for output and {% %} for logic, while Blade uses @{{ }} and @if. Mixing them without a bridge causes errors.
    • Fix: Stick to one syntax per project or use a Twig-Blade bridge (not natively supported).
  2. Template Paths:

    • Gotcha: The renderer defaults to resources/views/ but may not auto-discover subdirectories like Laravel’s View facade.
    • Fix: Explicitly set paths in config:
      'paths' => [
          resource_path('views'),
          resource_path('views/emails'),
          resource_path('views/pdf'),
      ],
      
  3. PDF Generation:

    • Gotcha: mPDF may fail silently or produce malformed PDFs if the Twig template lacks proper HTML structure (e.g., missing <html>, <body> tags).
    • Fix: Use a base Twig template for PDFs:
      {# resources/views/pdf/base.twig #}
      <!DOCTYPE html>
      <html>
          <head>
              <meta charset="UTF-8">
              <style>
                  body { font-family: Arial; }
              </style>
          </head>
          <body>
              {{ block('content') }}
          </body>
      </html>
      
  4. Caching Quirks:

    • Gotcha: Twig’s cache directory (storage/framework/views) may conflict with Laravel’s view cache.
    • Fix: Configure separate cache paths:
      'twig' => [
          'cache' => storage_path('framework/views/twig'),
      ],
      
  5. Markdown Parsing:

    • Gotcha: The derafu/markdown engine may not support all Markdown features (e.g., tables, footnotes).
    • Fix: Use a dedicated Markdown parser like michelf/php-markdown for complex cases:
      $markdown = Renderer::render('email.md', $data);
      $html = \Michelf\Markdown::defaultTransform($markdown);
      
  6. Dependency Conflicts:

    • Gotcha: derafu/twig may pull in older versions of twig/twig or symfony/dependency-injection, causing conflicts.
    • Fix: Pin versions in composer.json:
      "require": {
          "twig/twig": "^3.4",
          "symfony/dependency-injection": "^6.0"
      }
      

Debugging Tips

  1. Enable Twig Debug Mode: Add to config/renderer.php:
    'twig' => [
        'debug'
    
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity