A Laravel Blade parser, compiler, and static analyzer written in TypeScript.

Overview

Blade Parser

This library provides a Laravel Blade parser written in TypeScript. In addition to being able to parse Blade template files, this library also provides utilities and libraries that make it simpler to perform static analysis on Blade documents.

What this project is:

  • A standalone Blade parser written in TypeScript/JavaScript
  • A standalone Blade compiler written in TypeScript/JavaScript
  • A Blade static analysis library
  • A Blade error/diagnostics library
  • An advanced Blade document transformation library

What this project is not:

  • This project (when used by itself) is not a formatter. However, it can be used to quickly write a formatter. If you are looking for a formatter built from this project, you may checkout prettier-plugin-blade.
  • A view engine. It will not be able to actually render your Blade templates

Installing

This package can be installed in your project using the following command:

npm install --save stillat-blade-parser

Basic Usage

The simplest way to get started using this library is to use the BladeDocument.fromText static helper method:

import { BladeDocument } from "stillat-blade-parser/out/document/bladeDocument";

const document = BladeDocument.fromText(`<html>
    <head>
        <title>{{ $title }}</title>
    </head>
</html>`);

This method will return an instance of BladeDocument, which provides many useful features and helpers.

As an example, we can ask the document for a list of all parsed nodes and do something special with any directives we find:

import { BladeDocument } from "stillat-blade-parser/out/document/bladeDocument";
import { DirectiveNode } from 'stillat-blade-parser/out/nodes/nodes';

const document = BladeDocument.fromText(`<html>
    <head>
        <title>{{ $title }}</title>
    </head>
</html>`);

document.getAllNodes().forEach((node) => {
    if (node instanceof DirectiveNode) {
        console.log(node.directiveName);
    }
});

Parsing Options

The Blade parser can be configured with a few options to help guide the parser. These configurable options are:

  • customIfs: A list of custom if directives
  • directives: A list of directives that can be parsed
  • ignoreDirectives: A list of directive names that should be ignored

All provided option values are case-insensitive. Do not include the @ when supplying directive names to the directives or ignoreDirectives lists.

Supplying Options to the Parser

To supply parser options, you must have an instance of BladeDocument before you parse the template contents. Each BladeDocument also contains a parser instance. We can use the getParser() method to retrieve the internal parser instance, which will allow us to set our options:

import { BladeDocument } from "stillat-blade-parser/out/document/bladeDocument";
import { ParserOptions } from 'stillat-blade-parser/out/parser/parserOptions';

const document = new BladeDocument(),
    options:ParserOptions = {
        customIfs: [],
        directives: [],
        ignoreDirectives: []
    };

// Set the parser options.
document.getParser().withParserOptions(options);

document.loadString(`Template content`);

The directives and ignoreDirectives Options

The directives and ignoreDirectives options are mutually exclusive, and only one will be used at a time. If values are provided for the directives configuration option, it will take precedence over the ignoreDirectives option.

The ignoreDirectives option is the default configuration setup, and allows developers to supply a list of directive names that should not be parsed. Because this parser library does not have any runtime access to your project's specific directives, it will attempt to parse everything that could be a valid directive.

By default, the ignoreDirectives option is set to the following:

const options:ParserOptions = {
    customIfs: [],
    directives: [],
    ignoreDirectives: [
        'media',
        'charset',
        'import',
        'namespace',
        'supports',
        'document',
        'page',
        'font-face',
        'keyframes',
        'viewport',
        'counter-style',
        'font-feature-values',
        'swash',
        'ornaments',
        'annotation',
        'stylistic',
        'styleset',
        'character-variant',
        'font-variant-alternates',
        'property',
        'color-profile',
        'click',
        'submit', 
        'scroll',
        'keydown',
        'keypress',
        'keyup',
        'blur', 
        'change',
        'contextmenu',
        'copy',
        'cut',
        'paste',
        'dblclick',
        'drag',
        'dragend',
        'dragenter',
        'dragleave',
        'dragover',
        'dragstart',
        'drop',
        'focus',
        'focusin',
        'focusout',
        'input',
        'mousedown',
        'mouseenter',
        'mouseleave',
        'mousemove',
        'mouseover',
        'mouseout',
        'mouseup',
        'mousewheel',
        'resize',
        'select',
        'touchcancel',
        'touchend',
        'touchmove',
        'touchstart',
        'wheel'
    ]
};

Whenever a potential directive is encountered and is present in the ignoreDirectives list, that section of the template is skipped over and that potential directive becomes part of the document's literal text.

In contrast, the directives configuration option can be used to supply a list of directive names that can be parsed. If a potential directive is encountered that is not in this list, that potential directive is skipped and becomes part of the document's literal text.

The customIfs Configuration Option

The customIfs configuration option is the parser's counterpart to Laravel's Custom If Statements feature. An important thing to note is this configuration option simply hints to the parser what will become an if statement internally.

This option can be set like so:

const options:ParserOptions = {
    customIfs: [
        'disk',
    ],
    directives: [],
    ignoreDirectives: []
};

In most situations you do not need to supply any value for this configuration option. The parser is capable of analyzing your Blade templates and detecting custom if statements automatically.

Reporting Issues

Please use the issues feature on GitHub to report bugs/issues. For general questions on how to use this library, please use the Discussions feature. Be considerate when interacting with others :)

Due to the complexity and scope of this project, when reporting bugs/issues please include all required information to reproduce the bug or issue. You are encouraged to attach any problematic templates to the issue as a file in addition to being included in the issue description (this helps to eliminate any formatting/adjustments that the GitHub UI may apply).

Contributing Changes

Thank you for considering contributing changes to this project!

Building from Source

To build this project from source, issue the following commands:

npm install
npm run compile

If you introduce changes that break existing tests with un-important whitespace changes, it is fine to simply update those tests to account for the new whitespace changes. An example of these types of changes would be the transformer_ tests. Breaking whitespace inside literal/node content (unless its a bug fix) is not acceptable, however.

Running the Tests

Before opening a pull request, do try and ensure that new features/changes have corresponding tests created. In addition, make sure to correct any failing tests.

To run the test suite issue the following command:

npm run test:parser

Debugging the Parser Library

The easiest method to debug the parser library is to use VS Code and select the Blade Parser Run and Debug configuration. This debug configuration will launch the /out/parser.ts file in debug mode, allowing you to run and debug code from within that file right within VS Code.

License

This library is open-sourced software licensed under the MIT license.

If you find this project useful, or are using it in a commercial setting, please consider funding the project to ensure it's continued development.

You might also like...

A simple inefficient and buggy JSON parser written in JavaScript. Just a fun project

A simple inefficient and buggy JSON parser written in JavaScript. Just a fun project

A simple inefficient and buggy JSON parser written in JavaScript This JSON parser isn't guaranteed to work properly. Its recommended to use builtin JS

Feb 20, 2022

🦾 Tiny 2kb Markdown parser written, almost as fast and smart as Tony Stark

Starkdown 🦾 Starkdown is a Tiny 2kb Markdown parser written, almost as fast and smart as Tony Stark. npm i starkdown Motivation It is a continuation

Sep 22, 2022

An oversimplification of the TypeScript Compiler API for defining and generating source files.

An oversimplification of the TypeScript Compiler API for defining and generating source files.

Tanu 🦝 A simplified abstraction of the TypeScript Compiler API for defining and generating source files. Tanu 🦝 Why? What does Tanu mean? 🦝 How do

Oct 29, 2022

A dockerfile to build ARM cross-compiler for Tauri (React Typescript)

tauri-arm A dockerfile to build a ARM cross-compiler for Tauri(React Typescript Template). MacOS Windows 10 Linux Setup $ yarn Installation Please bu

Sep 6, 2022

A lightweight Adobe Photoshop .psd/.psb file parser in typescript with zero-dependency for WebBrowser and NodeJS

@webtoon/psd A lightweight Adobe Photoshop .psd/.psb file parser in typescript with zero-dependency for WebBrowser and NodeJS Browser Support Chrome F

Jan 1, 2023

TypeScript dotbim parser and encoder.

dotbim-ts Open-source TypeScript parser and encoder for dotbim file format. dotbim's website: https://dotbim.net/ Here you can find small manual for d

Aug 2, 2022

A Parsimmon-like, stateful parser-combinator library with TypeScript.

A Parsimmon-like, stateful parser-combinator library with TypeScript.

terrario A Parsimmon-like, stateful parser-combinator library with TypeScript. Try it out! The terrario is a parser-combinator library inspired by PEG

Dec 2, 2022

Instruction how to install laravel echo and pusher without vuejs or even npm

This 2 .js files are used to listen from server broadcasting with laravel-websockets, so that you don't need the use of Vue.js in your laravel app Fol

Sep 28, 2022

E-commerce website using Laravel, Tailwindcss and Alpine.js

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Dec 12, 2022
Comments
  • Unpaired condition control structure (bladeParser BLADE_002)

    Unpaired condition control structure (bladeParser BLADE_002)

    The following file shows an error:

    |6 col 2-3 error| [bladeParser BLADE_002] Unpaired condition control structure [E]
    
    {{-- foo.blade.php --}}
    @props(['model'])
    
    @can('update', $model)
        update
    @else
        any
    @endcan
    

    But I think that is a valid blade syntax.

    The first mention of this issue: https://github.com/yaegassy/coc-blade/issues/15

    opened by BrayanCaro 5
  • Directives with a lot of spaces

    Directives with a lot of spaces

    Parsing directives with a lot of spaces currently does strange things:

    @if                           ($something)
    
    @endif
    

    Keeping the amount of spaces sane does not produce an issue, however.

    opened by JohnathonKoster 0
JIT Compiler is a open source online code compiler. You can run more than 40+ most popular programming languages in your browser just-in-time using jitcompiler.

JIT Compiler is a open source online code compiler. You can run more than 40+ most popular programming languages in your browser just-in-time using jitcompiler.

Rajkumar Dusad 36 Jan 5, 2023
A markdown parser and compiler. Built for speed.

Marked ⚡ built for speed ⬇️ low-level compiler for parsing markdown without caching or blocking for long periods of time ⚖️ light-weight while impleme

Marked 28.9k Jan 7, 2023
Adds support for Blade templates to Prettier. (work in progress)

Laravel Blade support for Prettier ⚠️ This plugin is still a work-in-progress. If you're trying it out, please keep this in mind. This package include

Ryan Chandler 139 Sep 20, 2022
The full power of the Go Compiler directly in your browser, including a virtual file system implementation. Deployable as a static website.

Static Go Playground Features Full Go Compiler running on the browser. Supports using custom build tags. Incremental builds (build cache). Supports mu

null 25 Jun 16, 2022
Json-parser - A parser for json-objects without dependencies

Json Parser This is a experimental tool that I create for educational purposes, it's based in the jq works With this tool you can parse json-like stri

Gabriel Guerra 1 Jan 3, 2022
A lexical analyzer based on DFA that made by JS and supports multi-language extension

lexer 一个基于DFA法的支持多语言扩展的JS版开源词法分析器,快速了解与体验请查看线上网站 It is a lexical analyzer based on DFA that made by JS and supports multi-language extension. For quic

null 273 Dec 21, 2022
CSS selectors complexity and performance analyzer

analyze-css CSS selectors complexity and performance analyzer. analyze-css is built as a set of rules bound to events fired by CSS parser. Each rule c

Maciej Brencz 680 Dec 16, 2022
A GitHub action to run Dart analyzer with annotation support.

⚒️ GitHub Action for Dart Analyzer A GitHub action to run Dart analyzer with annotation support. License Usage name: "analyze" on: # rebuild any PRs a

Invertase 149 Dec 28, 2022
Jsonup - This is a zero dependency compile-time JSON parser written in TypeScript

jsonup This is a zero dependency compile-time JSON parser written in TypeScript.

TANIGUCHI Masaya 39 Dec 8, 2022
Gofiber with NextJS Static HTML is a small Go program to showcase for bundling a static HTML export of a Next.js app

Gofiber and NextJS Static HTML Gofiber with NextJS Static HTML is a small Go program to showcase for bundling a static HTML export of a Next.js app. R

Mai 1 Jan 22, 2022