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 to phpstan.neon:
      includes:
          - ./vendor/tomasvotruba/bladestan/config/extension.neon
      
  3. First Run:

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

    This enables the custom Blade error formatter with clickable template links.

First Use Case: Catching Undefined Methods

Run Bladestan on a controller returning a view with a Blade template:

// app/Http/Controllers/PostController.php
public function show(Post $post) {
    return view('posts.show', ['post' => $post]);
}

If posts/show.blade.php calls $post->nonexistentMethod(), Bladestan will flag it with:

Line 15 posts/show.blade.php: Call to undefined method App\Models\Post::nonexistentMethod().

Click the link to jump directly to the error in your IDE.


Implementation Patterns

Daily Workflow Integration

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

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

    Fail the hook if errors exist, enforcing Blade quality before code review.

  2. CI/CD Pipeline: Run Bladestan in your CI (e.g., GitHub Actions):

    - name: Run Bladestan
      run: vendor/bin/phpstan analyze --error-format=blade --level=max
    

    Set it to fail the pipeline on errors, mirroring your PHPStan checks.

  3. Onboarding New Developers: Include Bladestan in your README.md under "Local Setup":

    ## Local Setup
    1. Install dependencies: `composer install`
    2. Run Blade template checks: `vendor/bin/phpstan analyze --error-format=blade`
    

Advanced Patterns

  1. Custom Error Levels: Override default rule levels in phpstan.neon:

    parameters:
        level: max
        rules:
            Bladestan\Rules\UndefinedMethodRule: error
            Bladestan\Rules\MissingVariableRule: warning
    
  2. Ignoring False Positives: Suppress specific errors in phpstan.neon:

    includes:
        - ./vendor/tomasvotruba/bladestan/config/extension.neon
    ignoreErrors:
        - '#Call to undefined method App\Models\User::legacyMethod\(\) in .*\.blade\.php#'
    
  3. Livewire Component Analysis: Bladestan automatically detects Livewire components. For custom props, ensure your component class is type-hinted:

    // app/Http/Livewire/MyComponent.php
    public string $propName = '';
    

    Bladestan will validate usage in Blade templates like @livewire('my-component', ['propName' => $value]).

  4. Mail Template Validation: Extend Bladestan to analyze mail templates by adding their paths to phpstan.neon:

    parameters:
        bladeTemplatePaths:
            - resources/views
            - resources/views/emails
    
  5. Package Development: If building a Laravel package with Blade templates, include Bladestan in your composer.json under require-dev and document its use in your README.md:

    ## Static Analysis
    Run Blade template checks:
    ```bash
    vendor/bin/phpstan analyze --error-format=blade
    
    
    

Gotchas and Tips

Common Pitfalls

  1. Cache Invalidation: Bladestan invalidates PHPStan’s result cache when Blade templates change (since v0.11.5). If errors persist after fixes:

    vendor/bin/phpstan analyze --clear-cache
    
  2. Dynamic Includes: Errors may appear for @include directives with dynamic paths (e.g., @include($dynamicPath)). To debug:

    • Temporarily hardcode the path to isolate the issue.
    • Ensure the dynamic value resolves to a valid Blade template path.
  3. Livewire Component Props: Bladestan may flag Livewire props as undefined if the component class lacks type hints. Add PHPDoc annotations as a workaround:

    /** @property string $propName */
    
  4. Facade Calls: For Response::view() or View::make(), ensure the view name is a string literal or a resolved variable. Dynamic view names (e.g., View::make($dynamicView)) may trigger false positives.

  5. Non-HTML Templates: Bladestan supports non-HTML mail templates (since v0.11.0), but complex logic (e.g., @php blocks with dynamic includes) may require manual validation.

Debugging Tips

  1. Verbose Output: Run with --verbose to debug rule application:

    vendor/bin/phpstan analyze --error-format=blade --verbose
    
  2. Rule-Specific Debugging: Disable all rules except one to isolate issues:

    parameters:
        rules:
            Bladestan\Rules\UndefinedMethodRule: error
            *: disabled
    
  3. Template Paths: If Bladestan misses templates, explicitly define paths in phpstan.neon:

    parameters:
        bladeTemplatePaths:
            - resources/views
            - custom/template/path
    
  4. IDE Integration: For VS Code, use the PHPStan extension with the Blade formatter enabled to get inline errors.

Extension Points

  1. Custom Rules: Extend Bladestan by creating a custom PHPStan rule. Example:

    // app/Rules/CustomBladeRule.php
    namespace App\Rules;
    
    use PHPStan\Rules\Rule;
    use Bladestan\BladeNode;
    
    class CustomBladeRule implements Rule
    {
        public function getNodeTypeNames(): array
        {
            return [BladeNode::class];
        }
    
        public function processNode(BladeNode $node): array
        {
            if ($node->isDangerousPattern()) {
                return [$node->createError('Custom rule: Dangerous pattern detected.')];
            }
            return [];
        }
    }
    

    Register it in phpstan.neon:

    includes:
        - ./vendor/tomasvotruba/bladestan/config/extension.neon
        - ./app/Rules/CustomBladeRule.neon
    
  2. Error Formatter: Override the default Blade formatter by creating a custom formatter class and updating the CLI command:

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

    Configure in phpstan.neon:

    parameters:
        errorFormatter: App\CustomBladeErrorFormatter
    
  3. Template Parsing: For complex templates (e.g., custom directives), subclass Bladestan\BladeParser and override parsing logic. Example:

    // app/Blade/CustomParser.php
    namespace App\Blade;
    
    use Bladestan\BladeParser;
    
    class CustomParser extends BladeParser
    {
        protected function parseCustomDirective(string $content): void
        {
            // Custom logic for @customdirective
        }
    }
    

    Register the parser in your service provider:

    // app/Providers/AppServiceProvider.php
    public function register()
    {
        $this->app->singleton(BladeParser::class, function () {
            return new \App\Blade\CustomParser();
        });
    }
    

Configuration Quirks

  1. PHPStan Version: Bladestan requires PHPStan 2.0+. Check compatibility in composer.json:

    "require-dev": {
        "phpstan/phpstan": "^2.0"
    }
    
  2. Laravel Version: Ensure your laravel/framework version matches Bladestan’s support (Laravel 10–12 as of v0.11.5). For older versions, pin to a compatible release:

    composer require tomasvotruba/bladestan:0.10.0
    
  3. Livewire Support: If Livewire components are not detected, verify config/livewire.php includes the correct namespace and that the component class extends \Livewire\Component.

  4. Symfony Mailer: For Symfony mail templates, ensure config/services.php includes the mailables path:

    'mailables
    
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope