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

Twig Js Bundle Laravel Package

jms/twig-js-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps for Laravel Integration

Since jms/twig-js-bundle is Symfony-specific, Laravel developers must manually replicate its functionality. Here’s how to start:

  1. Install Dependencies

    composer require twig/twig
    composer require jms/twig-js  # Twig.js library (standalone)
    
  2. Set Up Twig in Laravel Create a service provider (app/Providers/TwigServiceProvider.php):

    namespace App\Providers;
    
    use Twig\Environment;
    use Twig\Loader\FilesystemLoader;
    use Illuminate\Support\ServiceProvider;
    
    class TwigServiceProvider extends ServiceProvider
    {
        public function register()
        {
            $loader = new FilesystemLoader($this->app->basePath('resources/views'));
            $twig = new Environment($loader);
            $this->app->singleton('twig', function () use ($twig) {
                return $twig;
            });
        }
    }
    

    Register it in config/app.php:

    'providers' => [
        // ...
        App\Providers\TwigServiceProvider::class,
    ],
    
  3. Compile Twig to JavaScript Create a custom Artisan command (app/Console/Commands/GenerateTwigJs.php):

    namespace App\Console\Commands;
    
    use Illuminate\Console\Command;
    use Twig\Environment;
    use Illuminate\Support\Facades\File;
    
    class GenerateTwigJs extends Command
    {
        protected $signature = 'twig:js:generate {path} {--output=public/js}';
        protected $description = 'Compile Twig templates to JavaScript';
    
        public function handle()
        {
            $twig = app('twig');
            $path = resource_path("views/{$this->argument('path')}");
            $outputDir = public_path($this->option('output'));
    
            $files = File::allFiles($path);
            foreach ($files as $file) {
                $relativePath = $file->getRelativePathname();
                $jsContent = $this->compileToJs($twig, $file->getPathname());
                File::put($outputDir.'/'.$relativePath.'.js', $jsContent);
            }
        }
    
        protected function compileToJs(Environment $twig, string $templatePath)
        {
            $template = $twig->loadFile($templatePath);
            // Use Twig.js to compile (simplified; see below for integration)
            return $this->generateJsFromTwig($template);
        }
    
        protected function generateJsFromTwig($template)
        {
            // Integrate Twig.js (standalone) here
            // Example: Use a JS compiler like `twig.js` via Node.js or PHP-JS bridge
            // For now, return a placeholder
            return "Twig.compile('{$template->getSource()}')";
        }
    }
    
  4. First Use Case Generate JS for a template:

    php artisan twig:js:generate partials
    

    This creates public/js/partials/your_template.js with the compiled Twig template.


Implementation Patterns

Workflow: Hybrid Templating

  1. Server-Side Rendering (PHP/Twig) Use Twig for server-rendered views (e.g., resources/views/home.blade.php with embedded Twig).

  2. Client-Side Hydration (JS)

    • Generate JS from Twig templates during build:
      php artisan twig:js:generate components
      
    • Include the JS in Blade:
      <script src="{{ asset('js/components/modal.js') }}"></script>
      
    • Hydrate dynamically:
      const template = Twig.templates['modal'];
      document.getElementById('modal-container').innerHTML = template.render({ data: userData });
      
  3. Dynamic Data Binding Pass PHP data to Twig, then expose it to JS:

    $data = ['user' => $user];
    $jsData = json_encode($data);
    return view('home', compact('jsData'));
    
    const userData = JSON.parse('{{ $jsData }}');
    

Integration Tips

  • Asset Pipeline: Use Laravel Mix/Vite to process .js files generated by Twig.js.
    // mix.js
    mix.js('public/js/compiled/*.js', 'public/js/twig-compiled.js');
    
  • Caching: Cache compiled JS to avoid regeneration:
    if (!File::exists($outputPath)) {
        File::put($outputPath, $jsContent);
    }
    
  • Partial Loading: Load JS for components only when needed:
    @if (request()->wantsJson())
        <script src="{{ asset('js/components/ajax-modal.js') }}"></script>
    @endif
    

Laravel-Specific Patterns

  1. Blade + Twig Coexistence Use Twig for dynamic parts within Blade:

    @php
        $twig = app('twig');
        $dynamicContent = $twig->render('partials/dynamic_part.twig', ['data' => $data]);
    @endphp
    <div id="dynamic-content">{{ $dynamicContent }}</div>
    <script>
        document.getElementById('dynamic-content').innerHTML =
            Twig.templates['dynamic_part'].render({ data: {{ json_encode($data) }} });
    </script>
    
  2. API-Driven Hydration Fetch Twig-compiled JS via API:

    Route::get('/template/{name}', function ($name) {
        $twig = app('twig');
        $template = $twig->render("templates/{$name}.twig");
        return response()->json(['js' => $this->compileToJs($template)]);
    });
    
    fetch('/template/modal')
        .then(res => res.json())
        .then(data => {
            eval(data.js); // Executes Twig.js-compiled template
        });
    
  3. Service Provider Extensions Extend the Twig service to include JS compilation:

    $this->app->afterResolving('twig', function ($twig) {
        $twig->addExtension(new class extends \Twig\Extension\AbstractExtension {
            public function getFunctions()
            {
                return [
                    new \Twig\TwigFunction('to_js', [$this, 'compileToJs']),
                ];
            }
            public function compileToJs($template)
            {
                // Integrate Twig.js here
                return "Twig.compile('{$template}')";
            }
        });
    });
    

    Usage in Twig:

    {{ template|to_js }}
    

Gotchas and Tips

Pitfalls

  1. Twig.js Deprecation

    • Twig.js is unmaintained (last update: 2014). Modern alternatives:
      • Alpine.js for lightweight reactivity.
      • Laravel Livewire for full-stack interactivity.
      • Inertia.js for React/Vue integration.
  2. Symfony-Specific Assumptions

    • The bundle assumes Symfony’s dependency injection and Twig environment. In Laravel:
      • Manually configure Twig\Environment.
      • Handle loader paths explicitly (e.g., FilesystemLoader).
    • Fix: Use a wrapper service to abstract differences.
  3. Asset Conflicts

    • Twig.js generates static .js files, which may conflict with:
      • Laravel Mix/Vite’s asset fingerprinting.
      • Caching headers (serve compiled JS with Cache-Control: immutable).
    • Fix: Process generated JS through your build pipeline.
  4. Template Syntax Mismatches

    • Twig.js does not support all Twig features (e.g., some filters, macros).
    • Fix: Test templates with Twig.js online compiler first.
  5. Security Risks

    • Compiled JS may expose template logic to clients.
    • Fix: Sanitize dynamic data before passing to Twig:
      $safeData = array_map('htmlspecialchars', $data);
      
  6. Performance Overhead

    • Client-side templating increases bundle size and parsing time.
    • Fix: Use code splitting (e.g., load JS for components on demand).

Debugging Tips

  1. Console Errors

    • Twig.js may throw errors in the browser console. Check:
      • Template syntax (e.g., missing {% endfor %}).
      • Variable scope (e.g., undefined {{ user.name }}).
    • Fix: Log Twig errors in PHP:
      $twig->getRuntimeLoader()->setRuntimeLoader(new class {
          public function loadRuntime($class) { /* ... */ }
      });
      
  2. Generated JS Validation

    • Verify compiled JS matches expected output:
      php
      
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui