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

Bladestan Laravel Package

tomasvotruba/bladestan

Bladestan adds PHPStan-powered static analysis for Laravel Blade templates. Install as a dev dependency and include its extension if needed. Provides a custom “blade” error formatter showing clickable template paths and where errors are rendered.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to Begin

  1. Installation:

    composer require --dev tomasvotruba/bladestan
    

    Add it to your composer.json under require-dev to ensure it runs in CI/CD pipelines.

  2. Configuration:

    • If using PHPStan’s extension installer, Bladestan auto-configures.
    • Otherwise, add this to your phpstan.neon:
      includes:
          - ./vendor/tomasvotruba/bladestan/config/extension.neon
      
  3. First Run: Analyze your Blade templates with the custom error formatter:

    vendor/bin/phpstan analyze --error-format=blade
    

    This will show clickable template paths and line numbers in errors, e.g.:

    Line 15 app/Views/post_codex.blade.php: Call to undefined method App\Entity\Post::getContent().
    

First Use Case: Catching Undefined Methods in Blade

Problem: A Blade template calls a non-existent method on a passed model:

@{{ post.getContent() }}  <!-- post is an App\Entity\Post, but getContent() doesn't exist -->

Solution:

  1. Run Bladestan:
    vendor/bin/phpstan analyze --error-format=blade
    
  2. Fix the error by either:
    • Adding getContent() to Post model.
    • Using the correct method (e.g., post->content).

Implementation Patterns

Daily Workflow Integration

  1. Pre-Commit Hooks: Add Bladestan to your pre-commit script (e.g., using husky or laravel-pint):

    # .husky/pre-commit
    vendor/bin/phpstan analyze --error-format=blade --level=5
    
    • Level 5 (strict) catches most Blade issues without false positives.
  2. CI/CD Pipeline: Run Bladestan in your CI (e.g., GitHub Actions) to block template errors:

    # .github/workflows/ci.yml
    - name: Run Bladestan
      run: vendor/bin/phpstan analyze --error-format=blade --level=5
    
  3. IDE Integration:

    • Use PHPStan’s IDE plugins (e.g., PHPStorm, VSCode) to get real-time Blade feedback.
    • Configure the plugin to use --error-format=blade for clickable links.

Advanced Patterns

1. Customizing PHPStan Rules for Blade

Override Bladestan’s default rules in phpstan.neon:

parameters:
    level: 5
    paths:
        - app
        - resources/views
    excludePaths:
        - tests
    blade:
        # Ignore specific undefined methods (e.g., legacy code)
        ignoredUndefinedMethods:
            - App\Models\Post::getLegacyContent
        # Treat @error directives as strict
        strictErrorDirectives: true

2. Analyzing Specific Templates

Target only critical templates (e.g., emails or admin views):

vendor/bin/phpstan analyze --error-format=blade resources/views/emails resources/views/admin

3. Livewire Component Validation

Bladestan supports Livewire components. To validate a component’s Blade template:

<!-- resources/views/livewire/counter.blade.php -->
<div>Count: {{ $count }}</div>

Run Bladestan to ensure $count is properly passed to the component.

4. Combining with Other Tools

  • Laravel Shift Blade Style: Use Bladestan for static analysis and laravel-shift/blade-style for linting/formatting.
  • Pint: Run Bladestan after pint to ensure formatted templates are also valid:
    ./vendor/bin/pint && ./vendor/bin/phpstan analyze --error-format=blade
    

Integration Tips

  1. Laravel Packages: Bladestan automatically analyzes Blade templates in published package views (e.g., vendor/package-name/resources/views). Ensure your package’s composer.json includes:

    "extra": {
        "laravel": {
            "views": "resources/views"
        }
    }
    
  2. Dynamic Blade Includes: For @include directives with dynamic paths (e.g., @include($dynamicView)), Bladestan may not resolve the template. Workaround:

    • Use static includes where possible.
    • Add a custom PHPStan rule to validate dynamic paths at the controller level.
  3. Mailables: Bladestan supports Laravel Mailables. To analyze a mail template:

    // app/Mail/OrderShipped.php
    public function build()
    {
        return $this->view('emails.orders.shipped');
    }
    

    Run Bladestan to catch undefined variables in resources/views/emails/orders/shipped.blade.php.


Gotchas and Tips

Pitfalls

  1. False Positives with Dynamic Data:

    • Issue: Bladestan may flag undefined methods if data is passed dynamically (e.g., $user->data->method() where data is an array).
    • Fix: Use @php directives to cast data or add type hints in your controllers:
      // Controller
      public function show(User $user)
      {
          return view('user.profile', [
              'userData' => $user->data instanceof Arrayable ? $user->data->toArray() : [],
          ]);
      }
      
  2. Caching Issues:

    • Issue: PHPStan’s result cache may not invalidate when Blade templates change, leading to stale analysis.
    • Fix: Clear the cache manually or rely on Bladestan’s auto-invalidation (v0.11.5+):
      vendor/bin/phpstan analyze --error-format=blade --no-cache
      
  3. Livewire Component Namespaces:

    • Issue: Bladestan may not resolve Livewire component classes if the namespace is misconfigured.
    • Fix: Ensure config/livewire.php has the correct component_namespace:
      'component_namespace' => 'App\\Livewire',
      
  4. Non-HTML Templates:

    • Issue: Bladestan may not fully support non-HTML templates (e.g., .txt or .md mail templates).
    • Fix: Exclude non-HTML templates from analysis or use @php to validate data:
      @php
          if (!method_exists($order, 'getTotal')) {
              throw new \RuntimeException('Order::getTotal() is missing!');
          }
      @endphp
      

Debugging Tips

  1. Verbose Output: Run Bladestan with --verbose to debug parsing issues:

    vendor/bin/phpstan analyze --error-format=blade --verbose
    
  2. Isolating Template Issues: Narrow down problems by analyzing a single file:

    vendor/bin/phpstan analyze --error-format=blade resources/views/post_codex.blade.php
    
  3. Custom Error Formatter Quirks:

    • The --error-format=blade flag may not work in all PHPStan versions. Fallback:
      vendor/bin/phpstan analyze | grep -A 2 -B 2 "rendered in:"
      

Extension Points

  1. Custom Rules: Extend Bladestan by creating a custom PHPStan rule for Blade-specific logic:

    // app/Rules/CustomBladeRule.php
    use PHPStan\Rules\Rule;
    use Bladestan\BladeNode;
    
    class CustomBladeRule implements Rule
    {
        public function getNodeTypeNames(): array
        {
            return [BladeNode::class];
        }
    
        public function processNode(Node $node): array
        {
            // Add custom logic here
            return [];
        }
    }
    

    Register it in phpstan.neon:

    services:
        - Bladestan\BladeNode
        - App\Rules\CustomBladeRule
    
  2. Ignoring Specific Errors: Suppress false positives by adding ignores to phpstan.neon:

    parameters:
        blade:
            ignoredUndefinedMethods:
                - App\Models\Post::legacyMethod
            ignoredUndefinedVariables:
                - $someDynamicVar
    
  3. Post-Processing Errors: Use PHPStan’s error formatter API to customize Bladestan’s output. Example:

    // app/Formatters/CustomBladeFormatter.php
    use PHPStan\Error\Error;
    use PHPStan\Output\ErrorFormatter;
    
    class CustomBladeFormatter implements ErrorFormatter
    {
        public
    
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.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony