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 Cs Fixer Laravel Package

vincentlanglet/twig-cs-fixer

A coding standards fixer for Twig templates. Analyze and automatically format Twig files with consistent style rules, configurable presets, and CI-friendly checks to keep templates clean and readable across your project.

View on GitHub
Deep Wiki
Context7

How to write a custom rule

Token-based rules

Token types

In order to write a custom rule, you first need to understand how the twig file is parsed. The TwigCsFixer\Token\Tokenizer transform the file into a list of tokens which can be:

  • TwigCsFixer\Token\Token::EOF_TYPE:

    This token is the last one of the file.

  • TwigCsFixer\Token\Token::TEXT_TYPE:

    Any basic text which are not inside {#, {{, {% delimiters. Does not include whitespaces.

  • TwigCsFixer\Token\Token::BLOCK_START_TYPE:

    The {% delimiter.

  • TwigCsFixer\Token\Token::VAR_START_TYPE:

    The {{ delimiter.

  • TwigCsFixer\Token\Token::BLOCK_END_TYPE:

    The %} delimiter.

  • TwigCsFixer\Token\Token::VAR_END_TYPE:

    The }} delimiter.

  • TwigCsFixer\Token\Token::NAME_TYPE:

    Any variable inside {% or {{ delimiters. Like name in {{ name }} or {% if foo(name) %}

  • TwigCsFixer\Token\Token::NUMBER_TYPE:

    Any number inside {% or {{ delimiters. Like 42 in {{ 42 }} or {% if foo(42) %}

  • TwigCsFixer\Token\Token::STRING_TYPE:

    Any single quote string or double quote string without interpolation string inside {% or {{ delimiters. Like 'string'/"string" in {{ 'string' }}, {% if foo('string') %}, {{ "string" }} or {% if foo("string") %}. It can also include part of string with interpolation, like both string in {{ 'string#{interpolation}string' }}.

  • TwigCsFixer\Token\Token::OPERATOR_TYPE:

    Any twig binary operator: arithmetic (+, -, *, /), logical (and, or), comparison (==, !=), member access (., ?.), filter (|), etc.

  • TwigCsFixer\Token\Token::UNARY_OPERATOR_TYPE:

    Any twig unary operator like not, -, +.

  • TwigCsFixer\Token\Token::TERNARY_OPERATOR_TYPE:

    The characters ? and : when used in ternary.

  • TwigCsFixer\Token\Token::PUNCTUATION_TYPE:

    One of the (, ), [, ], {, }, :, , characters. For :, only when it's not a ternary nor a slice operator.

  • TwigCsFixer\Token\Token::INTERPOLATION_START_TYPE:

    The characters #{ inside a double-quoted string. Like {{ "string #{interpolation}" }}.

  • TwigCsFixer\Token\Token::INTERPOLATION_END_TYPE:

    The characters } inside a double-quoted string. Like {{ "string #{interpolation}" }}.

  • TwigCsFixer\Token\Token::DQ_STRING_START_TYPE:

    The " used at the start of double-quoted string with interpolation. Like {{ "string#{interpolation}" }}.

  • TwigCsFixer\Token\Token::DQ_STRING_END_TYPE:

    The " used at the end of double-quoted string with interpolation. Like {{ "string#{interpolation}" }}.

  • TwigCsFixer\Token\Token::BLOCK_NAME_TYPE:

    The first non-empty element after the {% token. Like if in {% if ... %} or block in {% block ... %}.

  • TwigCsFixer\Token\Token::FUNCTION_NAME_TYPE:

    The name of a function. Like in {{ function(foo) }}.

  • TwigCsFixer\Token\Token::FILTER_NAME_TYPE:

    The name of a filter function. Like in {{ foo|filter(bar) }}.

  • TwigCsFixer\Token\Token::MACRO_NAME_TYPE:

    The name used in the definition of a macro function. Like foo in {% macro foo() %}.

  • TwigCsFixer\Token\Token::MACRO_VAR_NAME_TYPE:

    The name used for params of a macro function. Like bar in {% macro foo(bar) %}.

  • TwigCsFixer\Token\Token::TEST_NAME_TYPE:

    The name of a test function. Like in {% if foo is test(bar) %}.

  • TwigCsFixer\Token\Token::HASH_KEY_NAME_TYPE:

    Any hash key represented as name. Like foo in { foo: bar } or { foo } but not in { 'foo': bar }.

  • TwigCsFixer\Token\Token::TYPE_NAME_TYPE:

    Similar to hash key, but in types definition. Like foo in {% types { foo: 'bar' } %}.

  • TwigCsFixer\Token\Token::WHITESPACE_TYPE:

    Any whitespace separating text or expressions. Does not include commented whitespaces.

  • TwigCsFixer\Token\Token::TAB_TYPE:

    Any tabulation separating text or expressions. Does not include commented tabulations.

  • TwigCsFixer\Token\Token::EOL_TYPE:

    Any end of line except commented end of lines.

  • TwigCsFixer\Token\Token::COMMENT_START_TYPE:

    The {# delimiter.

  • TwigCsFixer\Token\Token::COMMENT_TEXT_TYPE:

    Any commented text. Does not include whitespaces.

  • TwigCsFixer\Token\Token::COMMENT_WHITESPACE_TYPE:

    Any commented whitespace.

  • TwigCsFixer\Token\Token::COMMENT_TAB_TYPE:

    Any commented tabulation.

  • TwigCsFixer\Token\Token::COMMENT_EOL_TYPE:

    Any commented end of line.

  • TwigCsFixer\Token\Token::COMMENT_END_TYPE:

    The #} delimiter.

  • TwigCsFixer\Token\Token::INLINE_COMMENT_START_TYPE:

    The # delimiter.

  • TwigCsFixer\Token\Token::INLINE_COMMENT_TEXT_TYPE:

    Any commented text inside an inline comment. Does not include whitespaces.

  • TwigCsFixer\Token\Token::INLINE_COMMENT_WHITESPACE_TYPE:

    Any commented whitespace inside an inline comment.

  • TwigCsFixer\Token\Token::INLINE_COMMENT_TAB_TYPE:

    Any commented tabulation inside an inline comment.

  • TwigCsFixer\Token\Token::NAMED_ARGUMENT_SEPARATOR_TYPE:

    The = or : separator used when using named argument. Like {{ foo(bar=true, baz: false) }}.

Rule

Then, the easiest way to write a custom rule is to implement the TwigCsFixer\Rules\AbstractRule class or the TwigCsFixer\Rules\AbstractFixableRule if the rule can be automatically fixed.

final class MyCustomRule extends \TwigCsFixer\Rules\AbstractRule {
    protected function process(int $tokenIndex, \TwigCsFixer\Token\Tokens $tokens): void
    {
        $token = $tokens->get($tokenIndex);
        if (!$token->isMatching(...)) {
            // Skip if the token is not matching some conditions.
            return;
        }
        
        $nextToken = $tokens->findNext(...); // Look for next token based on conditions.
        $previousToken = $tokens->findPrevious(...); // Look for previous token based on conditions.
        if (...) {
            // Skip if the token is valid.
            return;
        }
        
        // Use $this->addError(...) if the error is not fixable.
        $fixer = $this->addFixableError('Custom message.', $token);
        if (null === $fixer) {
            // Fixer is null when you're linting the file.
            return;
        }
        
        $fixer->beginChangeSet();
        // Use some of the following functions base of the wanted behavior:
        // $fixer->replaceToken(...);
        // $fixer->addNewline(...);
        // $fixer->addNewlineBefore(...);
        // $fixer->addContent(...);
        // $fixer->addContentBefore(...);
        $fixer->endChangeSet();
    }
}

Node-based rules

Rules can also be based on the Twig Node and NodeVisitor logic. Because they are different from the default token based rules, these rules have some limitations:

  • they cannot be fixable.
  • they can only report the line with the error but not the token position.

Still, these rules can be easier to be written for some static analysis. You can get inspiration from the src/Rules/Node folder.

final class MyCustomRule extends \TwigCsFixer\Rules\Node\AbstractNodeRule {
    public function enterNode(\Twig\Node\Node $node, \Twig\Environment $env): Node
    {
        // Do some logic
    }
}
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