Code Monkey home page Code Monkey logo

vscode-liquid's Introduction

       


  💧 LIQUIFY ~ INFORMATION ON THE FUTURE RELEASE

For quite some time users of this extension have been waiting for the next release (Liquify). Liquify will supersede this extension to facilitate advanced features and capabilities. Liquify is a big project which I began developing in 2020. This extension will continue to be maintained and slowly transition to Liquify.

Track progress in the Liquify RepositoryLiquify and the future of this extensionJoin the Discord and collaborate on the project

Liquid (vscode)

The essential vscode extension for Liquid (template language). Supports formatting, tag, filter, object, locale, snippet and schema auto-completions, hovers, syntax highlighting and diagnostic capabilities.

Key Features

  • Syntax Highlighting for Liquid in CSS, SCSS, JavaScript, Markdown and more!
  • Formatting support using Æsthetic.
  • Completions for Liquid tags, objects, filters, sections and more!
  • Embedded JSON Schema Tag language completions and diagnostics in Shopify theme sections.
  • Snippet auto-completion for Liquid tags and filters and Shopify Schema sections.
  • Integrated Schema stores that provide IntelliSense capabilities within Shopify JSON files.
  • Preserves VSCode HTML IntelliSense capabilities in .liquid files.
  • Informative Hover descriptions and reference links on tags, filters, objects and more!
  • Liquid Template Literal syntax highlighting support for TypeScript and JavaScript.
  • Hover descriptions and reference links on tags, filters, objects and more!

Showcase

showcase

Table of Contents

Updating to v4.0.0

Users who were upgraded to version 4.0.0 will need to align their configurations.

Command Palette

Below are the available commands exposed to the vscode command palette (cmd + shift + p)

Command Description
Liquid: Enable Formatting Enable Æsthetic formatting
Liquid: Disable Formatting Disable Æsthetic formatting
Liquid: Format Document Formats the current document
Liquid: Generate .liquidrc Generate a .liquidrc file with default rules
Liquid: Open Output Open the Liquid output panel
Liquid: Restart Extension Restarts the extension
Liquid: Release Notes Visit the Release notes (opens in browser)

Workspace Settings

The extension provides various workspace/user settings. Some options can be controlled using a .liquidrc configuration file. Take a look at the configuration section for more information on different settings. Below is a bare minimum sample that shows how you'd configure settings for your project.

By default, it is assumed you are using vscode workspace/user settings.

{

  // Liquid Formatting
  //
  // Leave the "editor.formatOnSave" option set to false.
  // You can enable it by pressing using the 💧 button in the status bar.
  //
  "[liquid]": {
    "editor.defaultFormatter": "sissel.shopify-liquid",
    "editor.formatOnSave": false
  },

  // Liquid Configuration
  //
  // If you are not using a .liquidrc file you can set the
  // "liquid.config.method" setting to "workspace"
  //
  "liquid.config.baseDir": ".",
  "liquid.config.method": "liquidrc",

  // Liquid Completion Settings
  //
  // These settings will enable/disable completions from showing.
  //
  "liquid.completion.tags": true,
  "liquid.completion.objects": true,
  "liquid.completion.filters": true,
  "liquid.completion.operators": true,
  "liquid.completion.schema": true,

  // Liquid Validations
  //
  // This setting will enable/disable validations in {% schema %} JSON
  //
  "liquid.validate.schema": true,

  // Liquid Hover Descriptions
  //
  // These settings will enable/disable hover descriptions from showing
  //
  "liquid.hover.tags": true,
  "liquid.hover.filters": true,
  "liquid.hover.objects": true,
  "liquid.hover.schema": true,

  // Uncomment if you are not using a .liquidrc file
  //
  // "liquid.engine": "shopify",

  // Uncomment if you are not using a .liquidrc file
  //
  // "liquid.files.shopify": {},
  // "liquid.files.11ty": {},

  //  Uncomment if you are not using a .liquidrc file
  //
  // "liquid.format.rules": {
  //   "ignore":[],
  //   "liquid": {},
  //   "html": {}
  // }

}

Syntax Support

Liquid syntax highlighting is applied using detailed token captures which extend upon the HTML derivative. The core grammars account for all token structures available in Liquid and have been developed with theming consideration in mind. Liquid contained within Markdown, YAML and JSON languages are supported using vscode injection grammars and applied in a non-conflicting manner. The injected grammars allow intelliSense capabilities provided by vscode in these languages to persist and work without interruption.

Supported Languages

Language Identifier Language Alias Supported Extension IntelliSense Support
liquid Liquid .liquid, or .jekyll
json JSON .json
yaml YAML .yaml
markdown Markdown .md, .md.liquid
liquid-css Liquid CSS .css.liquid 𐄂
liquid-scss Liquid SCSS .scss.liquid, sass.liquid 𐄂
liquid-javascript Liquid JavaScript .js.liquid 𐄂

Grammar Injections

In order to preserve vscode intellisense capabilities the below languages have Liquid grammars injected into them. The grammar injection will allow Liquid code to be highlighted and treated like the syntax exists as if it were part of the language.

  • JSON
  • Yaml
  • Markdown

When these languages contain Liquid syntax, vscode might complain about invalid code. You should consider disabling validations when they contain Liquid. Please be aware that in situations where you leverage linters or third party tools, Liquid syntaxes will typically be interpreted as invalid. It is up to you to take the necessary steps to disable and prevent such issues from becoming problematic to your development experience.

{
  // Disabling JSON validations when it contains Liquid syntax
  "json.validate.enable": false,

  // Disabling JavaScript validations when it contains Liquid syntax
  "javascript.validate.enable": false
}

Liquid in JSON, YAML and Markdown

Liquid tags, comments and object grammars are injected into JSON, YAML and Markdown languages. External language code regions and anything which requires an embedded language (ie: {% schema %}) are excluded. There is no need to use a .liquid suffix on these file names as Liquid syntax highlighting will be applied automatically.

If for any reason the injections become problematic then please report an issue.

Liquid in CSS, SCSS, SASS and JavaScript

Liquid syntax contained in JavaScript, CSS, SCSS, SASS and other supported languages require a .liquid extension suffix be applied on file names. The suffix will associate these languages to a designated grammar, for example:

.css    →   .css.liquid
.scss   →   .scss.liquid
.sass   →   .scss.liquid
.js     →   .js.liquid

If the required .liquid suffix is problematic to your use case then use file associations. Please note that the language native IntelliSense capabilities are not supported in the suffixed files.

Markdown Codeblock

Liquid markdown embedded code block regions are supported in .md files.

```liquid
{% if x %} {{ object.prop }} {% endif %}
```

Template Literal

Liquid template literals are supported for usage within JavaScript, JSX and TypeScript languages. The literal will provide both HTML and Liquid syntax highlighting. When expressing a template literal suffixed with liquid all containing code will have Liquid syntax highlighted.

liquid`{% if condition == true %} {{ object.prop }} {% endif %}`;

Take a look at Language Literals NPM module and the VSCode Extension for syntax highlighting and de-dentation logic of string input.

Frontmatter

The extension also provides additional syntax highlighting for language annotated frontmatter atop of YAML highlighting support. Language annotated frontmatter regions are typically implemented in 11ty projects.

// Frontmatter YAML
---
---

// Frontmatter JavaScript
---js
---

// Frontmatter JSON
---json
---

// Frontmatter TOML
---toml
---

Completions

The extension supports Standard and Shopify variation completions. This feature and will be improved upon as the extension progresses to Liquify, so the integration is elementary. Completions will be displayed in an intelligent manner.

{
  "liquid.completion.tags": true,
  "liquid.completion.objects": true,
  "liquid.completion.filters": true,
  "liquid.completion.operators": true,
  "liquid.completion.properties": true,
  "liquid.completion.sections": true,
  "liquid.completion.variables": true
}
Tags

Liquid tag completions are tokens which are encapsulated within {% and %} delimiters. Tag completions can be invoked by typing the % character.

Workspace Settings

{
  "liquid.completion.tags": true // Pass a value of false to disable
}
Objects

Liquid object completions will be invoked within tokens at different points. The parse algorithm will uses the previous character sequence to determine when object completions are to be provided. Object properties are triggered when a dot .character is typed that follows a known keyword (object) reference.

Workspace Settings

{
  "liquid.completion.objects": true // Pass a value of false to disable
}
Filters

Liquid filter completions will be invoked by typing the | character. Filter completions are persisted with whitespace, so the completion list will remain open when the previous character is determined to be a filter operator.

Workspace Settings

{
  "liquid.completion.filters": true // Pass a value of false to disable
}
Operators

Liquid operator completions will be invoked within control flow tokens such as {% if %}, {% elsif %} and {% unless %} tag types. Operator completions will be provided according to surrounding structures and support the and, or and contains keyword logics.

Workspace Settings

{
  "liquid.completion.operators": true // Pass a value of false to disable
}
Variables

Liquid variable completions are supported and made available a per-document basis. The extension will use your current cursor position when providing variable completions and only those which are accessible via the Liquid rendering engine will be shown. Liquid {% assign %} and {% capture %} tokens are analyzed and will be provided within completion items.

Workspace Settings

{
  "liquid.completion.variables": true // Pass a value of false to disable
}
Sections

Liquid section.* object completions are provided in accordance with the contents contained within {% schema %} embedded tags. Section completions are scope aware and respect block.type regions implemented with either control flow {% if %} or {% case %} tags. Tag completions support sensible re-assignment variable naming, which means you can assign to different names and completions will work. You can disable/enable Liquid section object completions within your workspace settings configuration.

Workspace Settings

{
  "liquid.completion.sections": true // Pass a value of false to disable
}

Files

The extension supports file completions. Depending on the specified Liquid engine variation defined, different types of file completions are made available. locale, settings, snippets and section file based completions but you will need to provide path references to enable this capability. You can provide path references in your .liquidrc file on files key. The paths must be relative to your projects root directory.

Using .liquidrc File

{
  "engine": "shopify",
  "files": {
    "locales": "locales/en.default.json",
    "settings": "config/settings_schema.json",
    "snippets": ["snippets/*.liquid"],
    "sections": ["sections/*.liquid"]
  }
}
Using Workspace Settings

If you defining configuration via workspace settings, the extension only supports project level definition references but does not support global (User Preferences) definitions for this setting. This means you can provide these references within your .vscode/settings.json file on a per-project level but you cannot provide this within your global configuration.

{
  // Shopify Liquid Variation
  // Expects the "engine" option to be using "shopify"
  //
  "liquid.files.shopify": {
    "locales": "",
    "settings": "",
    "snippets": [],
    "sections": []
  },

  // Eleventy Liquid Variation
  // Expects the "engine" option to be using "11ty"
  //
  "liquid.files.11ty": {
    "data": [],
    "includes": [],
    "layouts": []
  }
}

Shopify Schema

As of version v3.2^ this extension supports schema tag intelliSense capabilities. The feature drastically improves productivity for developers working with the Shopify Liquid variation. Section {% schema %} supports JSON features such as completions, validations, hovers and snippets. The contents of schema tags (ie: section settings and blocks) are made available to Liquid {{ section.settings.* }} and {{ block.settings.* }} objects.

{
  "liquid.completion.schema": true,
  "liquid.validate.schema": true
}
Completions

Embedded JSON contained within {% schema %} tags support completions in accordance with trigger characters. The JSON completions are made possible through Schema Stores maintained at @liquify/schema. VSCode Liquid has full IETF Support and also provides snippet (Ctrl + Space) triggers completions for settings and blocks. You can disable/enable JSON schema completions within your workspace settings configuration.

Workspace Settings

{
  "liquid.completion.schema": true // Pass a value of false to disable
}
Diagnostics

In addition to JSON and Liquid completion support, schema JSON diagnostic validation is also supported. This capability will warn you when incorrect or otherwise invalid JSON syntax and structures are provided. You can disable/enable JSON schema diagnostics within your workspace settings configuration.

Workspace Settings

{
  "liquid.validate.schema": true // Pass a value of false to disable
}

Syncify

The extension supports Syncify related Shopify theme development architecture. Syncify is a theme development tool which exists as superior alternative to the Shopify CLI. It introduces a refined approach to Shopify theme development and offers essential features for building brilliant themes.

I proactively oversee the development of Syncify, having conceived it as a solution to address what I consider a fundamentally flawed approach to Theme Development which has emerged with the Shopify CLI and Dawn.

Shared Section Schema

Shopify developers who leverage Syncify for theme development can take advantage of Shared Section Schema JSON IntelliSense capabilities. By default, all files using a .schema extension will be identified as Shared Section Schema and completions will be made available within {% schema %} tags using $ref occurrences. Whenever a .schema file is detected within your workspace, shared schema features will be activated

If you are currently utilizing the Shopify CLI, please be aware that this capability is unavailable to you.

Leveraging Shared Schema Files

All files in your workspace using a .schema extension will be treated as JSON by the extension. At runtime, your workspace is traversed and all .schema files are gathered and parsed automatically. Take a look at the Syncify Documentation for configuration and setup for shared schemas to ensure transforms are handled and injected correctly.

Schema Example

Take the follow shared schema. Below we define a what is known as a Settings Spread in a shared schema file named example.schema.

{
  "foo": [
      {
      "type": "checkbox",
      "id": "test",
      "label": "Some Example",
      "default": true
    }
    {
      "type": "text",
      "id": "title",
      "label": "Title",
      "info": "Lorem Ipsum"
    }
  ]
}

Reference Example

We can reference the above shared schema in any section {% schema %} tag by importing it using a $ref key property. We can target the foo settings spread using a <filename>.<schema> dot notation structure. The extension will automatically make $ref values available to schema in sections.

{% schema %}
{
  "name": "something",
  "settings": [
    {
      "$ref": "example.foo"
    }
  ]
}
{% endschema %}

Formatting

Formatting can be enabled/disabled via the command palette and references the language specific editor.formatOnSave vscode preference setting to determine whether or not it should be used. When Liquid formatting is enabled the extension will beautify Liquid and all suffixed *.liquid files. You can disable beautification by clicking the 💧 emoji icon in the status bar or exclude directories/files from handling using the format.ignore[] setting.

Æsthetic

Æsthetic is used to facilitate formatting capabilities under the hood. Æsthetic is built atop of the late but powerful Sparser lexing algorithm and has since been adapted for refined usage with Liquid and in particular this extension. Æsthetic exposes 30+ different formatting rules and supports Liquid beautification in various markup, script and style languages.

I actively maintain Æsthetic and it is currently in a pre-release (beta) stage. The ambition is to eventually have the tool become a competitive alternative to Prettier and disrupt "opinionated" conventions imposed upon the code nexus, one size does not fit all. Æsthetic is still in an early stage of development and has yet to ship an official release candidate but nonetheless it is stable enough for usage in languages like Liquid, HTML, JSON and CSS.

Æsthetic, once stable enough for the big time will be made available for usage in a separate extension

Setting Default Formatter

In some situations you may have another extension handling formatting and you will need to explicitly define an in-language editor.defaultFormatter within your vscode workspace/user settings. VSCode will typically inform you about this but if for any reason you are unable to get formatting to work, try setting the in-language default formatter.

Be sure to define only the languages you wish to have formatted by the extension.

{
  // Enables formatting of .liquid files
  "[liquid]": {
    "editor.defaultFormatter": "sissel.shopify-liquid",
    "editor.formatOnSave": true
  },
  // Enables formatting of all .css.liquid files
  "[liquid-css]": {
    "editor.defaultFormatter": "sissel.shopify-liquid",
    "editor.formatOnSave": true
  }
}

In addition to the above defaults, you can also choose to have Æsthetic format other supported languages.

{
  // Enables formatting of all .html files
  "[html]": {
    "editor.defaultFormatter": "sissel.shopify-liquid"
  },
  // Enables formatting of all .css files
  "[css]": {
    "editor.defaultFormatter": "sissel.shopify-liquid"
  },
  // Enables formatting of all .json files
  "[json]": {
    "editor.defaultFormatter": "sissel.shopify-liquid"
  },
  // Enables formatting of all .jsonc files
  "[jsonc]": {
    "editor.defaultFormatter": "sissel.shopify-liquid"
  }
}

Note

Æsthetic is still in its early stages and results may not be perfect. Extend with caution to languages other than Liquid/HTML

Ignoring Files

You can skip formatting on files, directories and code input a few different ways. If you are using workspace/user settings for configuration then you can pass a glob list of paths relative to the projects root using the liquid.format.ignore[] option. Folks leveraging the .liquidrc file for defining beautification rules can use the format.ignore[] setting.

Using .liquidrc File

{
  "format": {
    "ignore": []
  }
}
Using Workspace Settings

If you are using a .vscode/settings.json file to define formatting options, you can use the following structure:

{
  "liquid.format.rules": {
    "ignore": []
  }
}

Ignoring Code

In addition to file ignores, users can also take advantage of Æsthetic inline control comments. This will allow you to skip blocks of code or files from beautification.

Ignoring Next

Using esthetic-ignore-next comments can be annotated above tags blocks. Æsthetic will exclude the entire region of code when applying beautification.

<!-- esthetic-ignore-next-->
{% # esthetic-ignore-next %}
{% comment %} esthetic-ignore-next {% endcomment %}

Example

<div class="foo">

  {% # esthetic-ignore-next %}
  {% if condition %}
  {% if assertion %}
  THESE TAG BLOCKS WILL BE IGNORED
  {% endif %}
  {% endif %}

  {% if condition %}
    <section>
      THIS TAG BLOCK CODE WILL FORMAT
    </section>
  {% endif %}

</div>
Ignoring Regions

Using esthetic-ignore-start and esthetic-ignore-end can be wrapped around regions of code you wish to have excluded (ignored) from formatting.

<!-- esthetic-ignore-start -->
<!-- esthetic-ignore-end -->

{% # esthetic-ignore-next %}
{% # esthetic-ignore-end %}

{% comment %} esthetic-ignore-start {% endcomment %}
{% comment %} esthetic-ignore-end {% endcomment %}

Example

<div class="foo">

  {% # esthetic-ignore-start %}
  {% if condition %}
  {% if assertion %}
    THESE TAG BLOCKS WILL BE IGNORED
  {% endif %}
  {% endif %}
  {% # esthetic-ignore-end %}

  {% if condition %}
    <section>
      THIS TAG BLOCK CODE WILL FORMAT
    </section>
  {% endif %}

</div>
Ignoring Files

You can exclude entire files from formatting by placing the esthetic-ignore comment at the very top of documents. When provided, Æsthetic will skip beautification of the entire file.

<!-- esthetic-ignore -->
{% # esthetic-ignore %}
{% comment %} esthetic-ignore {% endcomment %}

Example

{% # esthetic-ignore %}

<div class="foo">

  {% if condition %}
  {% if assertion %}
    <!--
      THE ENTIRE FILE IS IGNORED
    -->
  {% endif %}
  {% endif %}

</div>

Using Prettier

Developers may prefer to use the Liquid Prettier Plugin for beautification instead of Æsthetic. Developers who prefer the Prettier solution. You will need to install the Liquid Prettier plugin as development dependencies in your project and also have the VSCode Prettier extension installed.

Setting Default Formatter

{
  "[liquid]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": false // change to true to enable formatting on save
  }
}

Snippets

Liquid snippets are supported in this extension. The filter and tag snippets were originally forked from vscode-liquid-snippets. The snippets provided do not expose trim ({%-) delimiters and you can instead leverage the liquid formatting rule of delimiterTrims for controlling this.

Note

You can also invoke tag completions by typing % which will automatically trigger a completion list.

Status Bar

When the extension is enabled and a supported *.liquid file has been opened in the editor you'll see an 💧 emoji appear in the bottom right hand side of the vscode status bar. This is the extensions status bar item and it will allow you to enable/disable formatting (programmatically), inform you when an ignored file is open and notifies you when the Æsthetic encounters any code errors during beautification.

The 💧 emoji will only show when a .liquid file is opened.

Status Command Action
Enabled Clicking the status bar item in this state will disable formatting
Disabled Clicking the status bar item in this state will enable formatting
Ignoring Clicking the status bar item in this state opens the output panel
Errors Clicking the status bar item in this state opens the output panel

Configuration

The extension provides 2 different ways for users to configure and control capabilities. Depending on how regularly you are working with Liquid should help determine which method is best for you. Using .liquidrc file is a great option for developers who prefer a single point of control and is typically the preferred approach. Developers who'd rather keep things to the editor can define all configurations in their workspace/user settings .vscode/settings.json file.

Using workspace settings

Setting configuration using workspace settings is made available on the liquid property. When a .liquidrc file is present in your projects root then that will take precedence over options defined in workspace/user settings.

Refer to Workspace Settings for defaults.

Using .liquidrc config file

The .liquidrc file allows users to specify their Liquid engine (variation), files for completions and format beautification rules. All other configuration options need to be defined within vscode workspace/user settings. The .liquidrc file is typically the easiest way to define per-project configurations and have shareable rules across projects. Whenever the extension detects the presence of a .liquidrc file it will behave in accordance and assume a Liquid project environment.

The .liquidrc file will be an essential requirement in Liquify (the future release) and the point of control for the Liquify parser, Language Server, Liquid specifications and other features. If you use Liquid a lot, then it a good idea to use this method.

Supported .liquidrc files

Currently, the extension only supports 2 JSON (with comments) file types:

  • .liquidrc
  • .liquidrc.json

Generating a .liquidrc file

You can generate a .liquidrc file using the Liquid: Generate .liquidrc file command from the vscode command palette. There are a few different configurations that can be applied when generating and you will be prompted accordingly. The default generated file will apply the recommended formatting preset of Æsthetic.You can progressively customize how beautification rules based off the recommended preset, this way you will not be overwhelmed by an extensive list of formatting options.

The recommended preset will produce an expected beautification style that most developers are happy with, however it is encouraged that you find your preferred style and leverage Æsthetic to its full potential.

{
  "engine": "shopify",
  "files": {
    "locales": "",
    "settings": "",
    "sections": [],
    "snippets": []
  },
  "format": {
    "ignore": [],
    "indentSize": 2,
    "preserveLine": 3,
    "wrap": 0,
    "wrapFraction": 0,
    "liquid": {},
    "markup": {},
    "style": {},
    "json": {},
    "script": {}
  }
}

Config Base Directory (optional)

The liquid.config.baseDir option can be used to define a relative directory path for resolving a .liquidrc (or .liquidrc.json) file. The option will only work in projects that use .liquidrc files. Consider the following directory layout:

 root
 ├─ .vscode
 │  └─ settings.json
 ├─ docs
 │  ├─ .liquidrc.json
 │  └─ index.liquid
 └─ src
    ├─ includes
    └─ views

By default, when no .liquidrc exists in the root of the opened project, then it is assumed settings have been defined in the .vscode/settings.json workspace file. If no settings are defined in the workspace file then the defaults will be used. In situations where you need the extension to use a config file that is located outside of the root of your project you can leverage the baseDir setting.

Targeting the .liquidrc.json file located in docs directory:

{
  "liquid.config.baseDir": "./docs"
}

The baseDir must point to a relative directory not a file. If the directory provided cannot be resolved, root is used.

Extension Conflicts

If you are using alternative extensions such as the Shopify Liquid (Theme Check) or Liquid Languages Support extension then you may run into some issues. The conflicts incurred will be caused because these extensions also target Liquid grammars and offers similar capabilities.

The vscode marketplace has 3 different extensions for Liquid support:

  • Liquid
  • Liquid Languages Support
  • Shopify Liquid (Theme Check)

This extension uses the Liquid display name and is considered the official Liquid extension for vscode by developers. It is recommended that you either uninstall or disable the Shopify Liquid (Theme Check) extension and make the choice between Liquid and using the Shopify backed one, more on this below.

Liquid Languages Support

If you are using or have installed the Liquid Languages Support extension then it is recommended that you either uninstall or disable it. The Liquid Languages Support extension is not maintained and the grammars are mostly obsolete. Using it along side this extension is problematic, boycott it, as it does nothing but increase the editors startup time.

Shopify Liquid (Theme Check)

If you are using or have installed Shopify Liquid (Theme Check) then you may need to choose (or alternate) between the Shopify Liquid (Theme Check) extension and this extension. The Shopify Liquid (Theme Check) extension is for Shopify projects (specifically themes) but tends to create a lot of noise.

Currently, this extension offers far more features and capabilities than the Shopify backed extension. Though there is efforts being made by Shopify to improve their approach (currently) the only upside for choosing it would be the validation features. The Liquify supersede will provide linting and validations upon its release, so the value proposition for continuing to choose this extension over Shopify Theme Check is minimal and one should evaluate whether or not it's the right choice for their productivity.

It is highly recommended that you uninstall or disable Shopify Theme Check if you are using this extension

Releases

As of v4.0.0 all version releases and changelogs including the distributed VSIX files can be found in Releases. Previous version changelogs can be found in the v2.3.0 branch.

Contributing

Contributions are welcome! This project uses pnpm for package management and is written in TypeScript.

  1. Ensure pnpm is installed globally npm i pnpm -g
  2. Leverage pnpm env if you need to align node versions
  3. Clone this repository git clone https://github.com/panoply/vscode-liquid.git
  4. Run pnpm i in the root directory
  5. Run pnpm dev for development mode

Developing

The project uses tsup for producing the distributed bundle. You can produce a VSIX by running the pnpm build command. The .vscode/launch.json file contains the extension host logic.

pnpm dev         # Development in watch mode
pnpm build       # Builds extension and packages VSIX
pnpm schema      # Imports all JSON schema stores and updates package.json contributes
pnpm grammar     # Generates object grammars and applies them to liquid.tmLanguage.json
pnpm dry         # Prints list of files that are packages into VSIX

Testing

The extension has undergone E2E and capability tests internally, but it does not leverage the vscode test suite. The extension itself is simple enough where extensive tests are not a matter of necessity. The contained test directory is used when invoking the debugger and extension host. Contained within that directory are various sample files that can be used for validating capabilities, grammars and invocation.

PR's are welcome for test cases, but be aware that the Liquify supersede will make them obsolete in due time.

Acknowledgements

Thanks to these 3 talented folks who's work, ideas, feedback and contributions make this extension possible.

Support

Follow me on Twitter and say hello! There is no obligation, but coffee is always appreciated.

PayPal: Donate
BTC: 35wa8ChA5XvzfFAn5pMiWHWg251xDqxT51


🥛 Νίκος Σαβίδης

vscode-liquid's People

Contributors

creeper0004 avatar haroldao avatar muchisx avatar panoply avatar polidario avatar tobiasdalhof avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vscode-liquid's Issues

How to ignore a line?

If I have the following line:

<div data-flickity='{ "autoPlay": 1000}'>

It gets replaced by:

<div data-flickity="{ 'autoPlay': 1000}">

Which is not ideal, and breaks that particular plugin. Is there a way to ignore this particular line when it comes to formatting? I've tried variations of this with no joy:

    "liquid.rules": {
      "ignore": [
        {
          "type": "liquid",
          "begin": "data-flickity",
          "end": "}"
        }
      ]
    }

front matter in scss

every front matter file starts with

---
// Some key value pairs if needed
---

but in scss files, vscode shows error. In standard scss file it is indeed error. But in liquid, it shouldn't be. Hence I can't save the file with format document enabled. I can still save the file manually outside vscode but then what's the point of using an IDE.

Extension issue (from VSCode automatic issue generator)

  • Issue Type: Bug
  • Extension Name: shopify-liquid
  • Extension Version: 2.3.0
  • OS Version: Linux x64 5.3.0-40-generic
  • VSCode version: 1.42.1
{
	"messages": [],
	"activationTimes": {
		"codeLoadingTime": 12,
		"activateCallTime": 5,
		"activateResolvedTime": 0,
		"activationReason": {
			"startup": false,
			"extensionId": {
				"value": "sissel.shopify-liquid",
				"_lower": "sissel.shopify-liquid"
			},
			"activationEvent": "onLanguage:html"
		}
	},
	"runtimeErrors": [
		{
			"name": "TypeError",
			"message": "Cannot read property 'document' of undefined"
		},
		{
			"name": "TypeError",
			"message": "Cannot read property 'document' of undefined"
		},
		{
			"name": "TypeError",
			"message": "Cannot read property 'document' of undefined"
		},
		{
			"name": "TypeError",
			"message": "Cannot read property 'document' of undefined"
		},
		{
			"name": "TypeError",
			"message": "Cannot read property 'document' of undefined"
		},
		{
			"name": "TypeError",
			"message": "Cannot read property 'document' of undefined"
		},
		{
			"name": "TypeError",
			"message": "Cannot read property 'document' of undefined"
		}
	]
}

help: closing braces of a liquid object

after saving a .liquid file, the closing braces of a liquid object receive a space, like so:

{{some_object}}

to this:

{{some_object} }

This completely breaks the highlighting and produces a syntax error during live editing. I am not sure if this is a problem with vscode or the extension. I am not using any other extensions and have disabled the vscode settings for inserting spaces before and after braces.

any help is appreciated so I can move on. thank you

Please publish in Open-VSX for VSCodium users

VSCodium, the telemetry-less fork of VSCode uses Open-VSX instead of Microsoft Marketplace due to licensing restrictions. I request you to publish this extension in Open-VSX too so that we can use it.

JSON part formatting problem

Before formatting
Screen Shot 2020-06-12 at 16 15 16

After formatting
Screen Shot 2020-06-12 at 16 15 40

Other parts are correctly formatted.

My extension configuration :

  "liquid.format": true,
  "liquid.rules": {
    "ignore": [
      {
        "type": "liquid",
        "begin": "comment",
        "end": "endcomment"
      },
      {
        "type": "html",
        "begin": "script",
        "end": "script"
      },
      {
        "type": "html",
        "begin": "style",
        "end": "style"
      }
    ],
    "html": {
      "correct": true,
      "force_attribute": false,
      "preserve": 2,
      "unformatted": false
    },
    "js": {
      "preserve": 1,
      "method_chain": 0,
      "quote_convert": "none",
      "format_array": "indent",
      "format_object": "indent",
      "braces": false,
      "no_semicolon": false,
      "brace_block": true
    },
    "scss": {
      "css_insert_lines": true,
      "preserve": 2,
      "braces": false,
      "brace_block": true
    },
    "css": {
      "css_insert_lines": true,
      "preserve": 2,
      "braces": false,
      "brace_block": true
    },
    "json": {
      "preserve": 0,
      "braces": false,
      "brace_block": true,
      "no_semicolon": true
    }
  }

Does anyone have any idea?
Thanks in advance!

Formatter breaks content inside script tag

Hi, I am trying to format a .liquid which contains script tag, somehow the formatter would modify the content without good intent.
I searched all the internet and cant find myself an answer. Any idea would be appreciated, cheers!
This issue will be more likely to occur when you have more than one script tag in the file.

Before:

<script type="application/ld+json">
  {
    "@context": "http://schema.org",
    "@type": "Organization",
    "name": "{{ shop.name }}",
  {% if settings.logo %}
    "logo": "https:{{ settings.logo | img_url: '450x' }}",
  {% endif %}
  "sameAs": [
      "{{ settings.social_twitter_link }}",
      "{{ settings.social_facebook_link }}",
      "{{ settings.social_pinterest_link }}",
      "{{ settings.social_instagram_link }}",
      "{{ settings.social_tumblr_link }}",
      "{{ settings.social_snapchat_link }}",
      "{{ settings.social_youtube_link }}",
      "{{ settings.social_vimeo_link }}"
    ],
    "url": "{{ shop.url }}{{ page.url }}"
  }
</script>

After:

<script type="application/ld+json">

�[36mLine: 2�[0m
�[31m(empty line)�[0m
�[31m�[36mLine: 1�[0m�[0m
�[31m�[31m�[36 mLine : 2 �[�[0m�[0m
�[31m�[31m        0 m �[�[0m�[0m
�[31m�[31m            31 mundefined�[�[0m�[0m
�[31m�[31m                0 m �[�[0m�[0m
�[31m(empty line)�[0m
</script>
Screen.Recording.2021-08-10.at.3.15.44.pm.mov

Inline JSON gets messed up

Hi,

I love this extension and to the most part it works pretty well. It does however mess up when you have inline schema data like this:

{% if template.name == 'index' %}
<script type="application/ld+json">
    {
      "@context": "http://schema.org",
      "@type": "WebSite",
      "name": "{{ shop.name }}",
      "potentialAction": {
        "@type": "SearchAction",
        "target": "{{ shop.url }}/search?q={search_term_string}",
        "query-input": "required name=search_term_string"
      },
      "url": "{{ shop.url }}{{ page.url }}"
    }
  </script>
{% endif %}

as it is converted to this:

<script type="application/ld+json">


�[36mLine: 1�[0m
�[31m�[36 mLine : 1 �[�[0m
�[31m        0 m �[�[0m
�[31m            31 m�[�[0m
�[31m                36 mLine : 2 �[�[0m
�[31m                    �[�[0m
�[31m                        0 m �[�[0m
�[31m                            31 m 0 m �[�[0m

</script>

{% if template.name == 'index' %}
  <script type="application/ld+json">


�[36mLine: 2�[0m
�[31m(empty line)�[0m
�[31m(empty line)�[0m
�[31m�[36mLine: 1�[0m�[0m
�[31m�[31m�[36 mLine : 1 �[�[0m�[0m
�[31m�[31m        0 m �[�[0m�[0m
�[31m�[31m            31 m {�[0m�[0m
�[31m�[31m                �[�[0m�[0m

</script>
{% endif %}

I've already verified that I don't have the other Liquid extensions known to cause issues, and I also have Prettier disabled on this test.

Any way I can get around this?

Extension should only affect liquid tags

I had to uninstall this plugin because it was causing syntax errors in my other projects which are written with Angular.

When I saved a .html file in Angular this extension was auto "correcting" syntax from routerLink to routerlink. This broke all links in my Angular project. This is just one example.

This extension should only be affecting liquid syntax, not all HTML syntax.

indent_size for HTML

Would be nice to be able specify the indent size for html tags when parsing and formatting liquid files. As far as I can see, it defaults to 4 and can't be changed, and also ignores editor.tabSize setting (which, in my case, is set to 2, and is respected when I trigger the built-in formatting of vsCode (Ctrl+Shift+i on Linux)).

Schema not formatting correctly

Hey - I've got a funky issue where when I format a .liquid file with a {% schema %} section, the liquid code formats perfectly but the formatter adds about 50 newlines between the {% schema %} tags and their containing JSON, and removes all indents from the schema JSON. See screenshots:

image

image

Here's my .liquidrc, not sure if I'm doing something wrong?

image

Thanks for any help! And cheers for a fantastic extension!

.scss.liquid issue

Sorry if this is an issue with scss support, but if scss.liquid is supported then why there is an error for not valid scss syntax?
Captura de pantalla de 2020-03-03 11-03-51
Should I report it on the scss support page ?

Format Handles Whitespace

Convert things like:

{{foo.bar}}         -> {{ foo.bar }}
{%if foo%}          -> {% if foo %}
{{ foo|asset_url }} -> {{ foo | asset_url }} 

As it is the recommended syntax, and would greatly improve the crazy inconsistencies in peoples' code 😁

Hope to make liquid code foldable

Screen Shot 2020-07-29 at 12 43 29

Feature request

Get folding with liquid code()

We can fold HTML code, but not liquid code, hope someone can help us.
Thanks!!!

Command 'Liquid Generate a .liquidrc rule file' fails again

Renew issue #24
As already talked about in #24 it seems it's happening again for some reason.
I do work just in a simple shopify theme folder structur which is generally not really a project folder structure. But as I read from linked issue it should work also for non-workspace environments.

Could you go over it again?

Formatting issues

Is this normal behavior?

shopify_ffol-1568046253555
shopify_ffol-1568046282171

If I change the Language Mode to Liquid instead of HTML it does no formatting at all.

I have the following in my .liquidrc

{
  "ignore": [
    {
      "type": "liquid",
      "begin": "comment",
      "end": "endcomment"
    },
    {
      "type": "html",
      "begin": "script",
      "end": "script"
    },
    {
      "type": "html",
      "begin": "style",
      "end": "style"
    }
  ],
  "html": {
    "correct": true,
    "force_attribute": true,
    "braces": true,
    "brace_block": true,
    "wrap": 2,
    "preserve": 0,
    "unformatted": false
  },
  "js": {
    "preserve": 1,
    "method_chain": 0,
    "quote_convert": "none",
    "format_array": "indent",
    "format_object": "indent",
    "braces": false,
    "no_semicolon": false,
    "brace_block": true
  },
  "scss": {
    "css_insert_lines": true,
    "preserve": 2,
    "braces": false,
    "brace_block": true
  },
  "css": {
    "css_insert_lines": true,
    "preserve": 2,
    "braces": false,
    "brace_block": false
  },
  "json": {
    "preserve": 0,
    "braces": false,
    "brace_block": true,
    "no_semicolon": true
  }
}

Am I missing something? Thanks in advance!

Respect editor settings or allow using tabs

My project is set to use tabs everywhere (except for yaml), but the auto-formatter in this extension does not respect that, and I cannot see a way to customise indenting behaviour for HTML in the liquidrc.

Could this extension either respect the indent preferences or allow the indenting options to be set for all liquid file types?

Highlighting does not work

My liquid files look like this...
Screen Shot 2020-11-24 at 5 03 55 PM

In addition, it keeps formatting to 4 spaces vs. 2 spaces — how can I correct this?

Liquid syntax is throwing an error

I'm using this extension for the first time. I have a .js.liquid file but after installing this extension I get the following error on liquid syntax:

image

Can someone help me figure out what could be wrong? I have not made any changes to the generated .liquidrc file yet.

PrettyDiff: 1 more end type than start types.

Figured I'd make this its own issue, though seems related to #42

The error:

[1/25/2021, 9:51:32 PM] PrettyDiff: 1 more end type than start types.

On every save. I swear it was formatting this document fine until... Something. And now this. I don't see anything wrong with my document 🤔

Snippet for checkbox setting has invalid default value

The snippet for a checkbox setting results in this code:

{
    "type": "checkbox",
    "id": "id",
    "label": "label",
    "default": "true",
    "info": ""
},

However, the default value needs to be boolean and not string - the hypens need to be removed.
Furthermore, I think it would be better to remove the comma from the snippets. Much more often, I happen to have a comma too much now in my schemas instead of one to few.

Any liquid.setting is seen as an error

I have some Liquid tags in my <style> in order to change colors in the Shopify Customizer.

<style> #bar-container { position: relative; top: 65px; z-index: 5; width: 100%; background-color: {{ section.settings.announcement_bg }} ; /* Having the BG color available in the customizer */ height: 40px; display: flex; align-items: center; font-size: 14px; } </style>

The {{ section.settings.announcement_bg }} gives the error: "property value expected".

Any way of ignoring these errors?

Comments

The Add line comment command, or similar, creates <!-- foo --> within .liquid files.
It might be preferable for it to create {% comment %} foo {% endcomment %} instead, if possible?

The benefit being that the liquid compiler will strip these out, so it is the best way to add comments to liquid files, typically

Indent 2 spaces instead of 4

Hey, is it possible to format the liquid document using 2 spaces? I have it set to 2, but when I use the liquid formatter it always formats to 4 spaces. Thanks!

Comments with Quotes Cause Strange HTML Injection

Input:

<html>
  <head>
    {% comment %}
     apostrophe's
    {% endcomment %}
  </head>
  <body>
  </body>
</html>

Formatted:

<html>
  <head>
    {% comment %}
     apostrophe's
    {% endcomment %}
  </head>
  <body>
  </body>
</html>
  </head>
</html> 

And after every format it injects another..

  </head>
</html>

..every single time!

It appears to only happen when a comment contains an ' apostrophe or " quote, which is quite bizarre :)

Formatting splits td tags

When I try to format a table, it splits some of the td tags to 2 lines like this.

        <td>{{Product.TotalSum}}
            €</td>

Is there a way to prevent td tags from breaking?

Shopify Code in JS Reported as Error

I am not 100% sure if this is an issue with this extension, if I have it configured wrong, or if I should have disabled something else. I just recently started with Shopify so please forgive me.

I am seeing that the following code, see below, gets a "Property Assignment expected error on the first { after "addToCart: "and then 4 errors for Decloration or statement expected.

<script> // Override default values of shop.strings for each template. // Alternate product templates can change values of // add to cart button, sold out, and unavailable states here. theme.productStrings = { addToCart: {{ 'products.product.add_to_cart' | t | json }}, soldOut: {{ 'products.product.sold_out' | t | json }}, unavailable: {{ 'products.product.unavailable' | t | json }} } </script>

Again, not sure is this is truley replated to the extension or note.
Thanks for any help.

Can't enable formatting

Hi,

I recently downloaded your extension and everything seemed to work perfectly, I had no problem with syntax coloring or suggestions, but then I noticed I couldn't format Liquid code. I tried reinstalling and putting a .liquidrc in my root folder but nothing changed.

I noticed that the tag in the status bar always displayed a cross, even after clicking on it, even though an activation message pops up. A deactivation message never pops up, no matter how many times I press the button.
bug

Note that clicking this button still checks the "Liquid: Format - Whether to enable/disable Liquid formatting." VS Code setting. On the other hand, changing the setting itself will not change the status bar button in any way.

Do you have any idea what could be causing this?

Can't Disable Snippets

I was fine with these before, but now i'm noticing that they're taking precedent over Emmet snippets which is fairly annoying.

is there a flag to be able to disable snippets suggestions just from the extension?

PrettyDiff: 2 more start types than end types.

When attempting to format a large file (.liquid) I get an error in the output panel "PrettyDiff: 2 more start types than end types." and the document is not formatted.

I assume this means the document cannot be formatted due to a syntax error but there is no hint as to which line. I tested the extension on a small document and it worked without issue.

What does this error code mean? How can I determine the source of the syntax error?

Formatter changes single quotation to double quotation in HTML markup per default

When I format a liquid file with the formatter provider by vscode-liquid, the formatter changes single quotation marks of the HTML markup code to double quotations, all the time.

The default HTML formatter of vscode handles it correctly by keeping it as is.

Single quotations might be rarely used, but they can for example be useful when JSON data is provided via an HTML attribute's value. As JSON is bitchy about requiring double quotations all the time, the solution is to surround the value of the HTML attribute with single quotations to be able using double quotations in the value itself.

Example:

<body class="l-{{data.template}}" data-controller="font" data-font-families-value='["Sailec"]' data-font-loaded-families-value="[]">
</body>

When formatting with vscode-liquid, it will result in this (see data-font-families-value value):

<body class="l-{{data.template}}" data-controller="font" data-font-families-value="['Sailec']" data-font-loaded-families-value="[]">
</body>

I noticed earlier the day, when my client-side JavaScript code threw an error due to not being able to JSON parse the value it got from the HTML elements.

Command not found errors

Hey,

Using the current extension, on latest VS Code, none of the commands work, yet they do show up as an option.

After some digging, I've installed the project dependencies in the extension directory

~/.vs-code/extensions/sissel.shopify-liquid-2.3.0

Restarted the VS Code, and everything now works :-)

Formatter isn't handling {% style %} well

Snippet pulled from Shopify/Dawn theme.

Before:

{% style %}
     {{ settings.type_body_font | font_face: font_display: 'swap' }}
     {{ body_font_bold | font_face: font_display: 'swap' }}
     {{ body_font_italic | font_face: font_display: 'swap' }}
     {{ body_font_bold_italic | font_face: font_display: 'swap' }}
     {{ settings.type_header_font | font_face: font_display: 'swap' }}

     :root {
       --font-body-family: {{ settings.type_body_font.family }}, {{ settings.type_body_font.fallback_families }};
       --font-body-style: {{ settings.type_body_font.style }};
       --font-body-weight: {{ settings.type_body_font.weight }};

       --font-heading-family: {{ settings.type_header_font.family }}, {{ settings.type_header_font.fallback_families }};
       --font-heading-style: {{ settings.type_header_font.style }};
       --font-heading-weight: {{ settings.type_header_font.weight }};

       --color-base-text: {{ settings.colors_text.red }}, {{ settings.colors_text.green }}, {{ settings.colors_text.blue }};
       --color-base-background-1: {{ settings.colors_background_1.red }}, {{ settings.colors_background_1.green }}, {{ settings.colors_background_1.blue }};
       --color-base-background-2: {{ settings.colors_background_2.red }}, {{ settings.colors_background_2.green }}, {{ settings.colors_background_2.blue }};
       --color-base-solid-button-labels: {{ settings.colors_solid_button_labels.red }}, {{ settings.colors_solid_button_labels.green }}, {{ settings.colors_solid_button_labels.blue }};
       --color-base-outline-button-labels: {{ settings.colors_outline_button_labels.red }}, {{ settings.colors_outline_button_labels.green }}, {{ settings.colors_outline_button_labels.blue }};
       --color-base-accent-1: {{ settings.colors_accent_1.red }}, {{ settings.colors_accent_1.green }}, {{ settings.colors_accent_1.blue }};
       --color-base-accent-2: {{ settings.colors_accent_2.red }}, {{ settings.colors_accent_2.green }}, {{ settings.colors_accent_2.blue }};
       --payment-terms-background-color: {{ settings.colors_background_1 }};
     }

     *,
     *::before,
     *::after {
       box-sizing: inherit;
     }

     html {
       box-sizing: border-box;
       font-size: 62.5%;
       height: 100%;
     }

     body {
       display: grid;
       grid-template-rows: auto auto 1fr auto;
       grid-template-columns: 100%;
       min-height: 100%;
       margin: 0;
       font-size: 1.5rem;
       letter-spacing: 0.06rem;
       line-height: 1.8;
       font-family: var(--font-body-family);
       font-style: var(--font-body-style);
       font-weight: var(--font-body-weight);
     }

     @media screen and (min-width: 750px) {
       body {
         font-size: 1.6rem;
       }
     }
   {% endstyle %}

After document formatting:

{% style %}

   {{settings.type_body_font | font_face: font_display: 'swap'}}{{body_font_bold | font_face: font_display: 'swap'}}{{body_font_italic | font_face: font_display: 'swap'}}{{body_font_bold_italic | font_face: font_display: 'swap'}}{{settings.type_header_font | font_face: font_display: 'swap'}}:root {
     --font-body-family: {{settings.type_body_font.family}}, {{settings.type_body_font.fallback_families}};
     --font-body-style: {{settings.type_body_font.style}};
     --font-body-weight: {{settings.type_body_font.weight}};

     --font-heading-family: {{settings.type_header_font.family}}, {{settings.type_header_font.fallback_families}};
     --font-heading-style: {{settings.type_header_font.style}};
     --font-heading-weight: {{settings.type_header_font.weight}};

     --color-base-text: {{settings.colors_text.red}}, {{settings.colors_text.green}}, {{settings.colors_text.blue}};
     --color-base-background-1: {{settings.colors_background_1.red}}, {{settings.colors_background_1.green}}, {{settings.colors_background_1.blue}};
     --color-base-background-2: {{settings.colors_background_2.red}}, {{settings.colors_background_2.green}}, {{settings.colors_background_2.blue}};
     --color-base-solid-button-labels: {{settings.colors_solid_button_labels.red}}, {{settings.colors_solid_button_labels.green}}, {{settings.colors_solid_button_labels.blue}};
     --color-base-outline-button-labels: {{settings.colors_outline_button_labels.red}}, {{settings.colors_outline_button_labels.green}}, {{settings.colors_outline_button_labels.blue}};
     --color-base-accent-1: {{settings.colors_accent_1.red}}, {{settings.colors_accent_1.green}}, {{settings.colors_accent_1.blue}};
     --color-base-accent-2: {{settings.colors_accent_2.red}}, {{settings.colors_accent_2.green}}, {{settings.colors_accent_2.blue}};
     --payment-terms-background-color: {{settings.colors_background_1}};
   }

   *,
   *::before,
   *::after {
     box-sizing: inherit;
   }

   html {
     box-sizing: border-box;
     font-size: 62.5%;
     height: 100%;
   }

   body {
     display: grid;
     grid-template-rows: auto auto 1fr auto;
     grid-template-columns: 100%;
     min-height: 100%;
     margin: 0;
     font-size: 1.5rem;
     letter-spacing: 0.06rem;
     line-height: 1.8;
     font-family: var(--font-body-family);
     font-style: var(--font-body-style);
     font-weight: var(--font-body-weight);
   }

   @media screen and(min-width: 750px) {
     body {
       font-size: 1.6rem;
     }
   }

   {% endstyle %}

Liquid formatter throws error

Hey panoply, big fan of the extension, it was the main reason I moved away from my old editor to VSCode, so thanks for all your time and effort.

I'm experiencing a new issue since the update to 1.6.2 which fixes the ignore comments bug. The update throws errors when formating using document and selection format commands:

Liquid Document could not be formatted, check your code!

Liquid Format Failed! The selection is invalid or incomplete!

This has been tested on a bare bones liquid file containing a single liquid stastement, a clean install of VSCode (Win 64), a clean settings json and no other extensions installed.

Liquid files are auto detecting as HTML and I see no liquid switch in the bottom status bar for controlling Liquid formating on/off, in case any of that is relevant.

Syntax highlighting, snippets and autocomplete are functioning as before.

Liquid tag indenting messed up

I might be missing something but

{%- for item in include.data -%}
    {% assign newItem = item[1] -%}
{%- endfor -%}

ends up as

{%- for item in include.data -%}
{% assign newItem = item[1] -%}
{%- endfor -%}

Same for if.

I tried the code in the PrettyDiffs web app and indenting is correct.

thanks

Formatting breaks json-ld script blocks

I'm working with the shopify default dawn theme and there are some microdata blocks in the header.liquid.
If i try to format the document, everything seems to work fine, but the json-ld blocks are broken afterwards.

It goes from:


<script type="application/ld+json">
    {
      "@context": "http://schema.org",
      "@type": "Organization",
      "name": {{ shop.name | json }},
      {% if section.settings.logo %}
        {% assign image_size = section.settings.logo.width | append: 'x' %}
        "logo": {{ section.settings.logo | img_url: image_size | prepend: "https:" | json }},
      {% endif %}
      "sameAs": [
        {{ settings.social_twitter_link | json }},
        {{ settings.social_facebook_link | json }},
        {{ settings.social_pinterest_link | json }},
        {{ settings.social_instagram_link | json }},
        {{ settings.social_tiktok_link | json }},
        {{ settings.social_tumblr_link | json }},
        {{ settings.social_snapchat_link | json }},
        {{ settings.social_youtube_link | json }},
        {{ settings.social_vimeo_link | json }}
      ],
      "url": {{ shop.url | append: page.url | json }}
    }
  </script>

to


<script type="application/ld+json">

�[36mLine: 1�[0m
�[31m�[36 mLine : 1 �[�[0m
�[31m        0 m �[�[0m
�[31m            31 m {�[0m
�[31m                �[�[0m
�[31m                    0 m �[�[0m
�[31m                        31 m "@context" : "http://schema.org",�[0m
�[31m                        �[�[0m
</script>

I've copied this block in a blank liquid file… same problem.

Is there any way, to exclude formatting those blocks?
Or can i adjust some other setting?

If you need further information, just ask.
Thanks for the otherwise great extension 👍

Formatting Overridden by Prettier

If you use Prettier, its HTML formatting trumps this plugin and makes a huge hot mess.
There is a workaround which is that you can set your workspace settings along the lines of

{  
  "settings": {
    "editor.formatOnSave": true,
    "[html]": {
      "editor.defaultFormatter": "sissel.shopify-liquid"
    }
  }
}

Which will force this plugin to be the default formatter for HTML language files.
Obviously that'll apply to filetypes other than .liquid, which isn't ideal but most likely fine for a Jekyll/Shopify project.
Perhaps it could be built-in as an option, to this plugin? Might not be possible. Either way this issue could be closed and stay here to help anyone with the same problem.

PS: Fantastic plugin, thank you @panoply ! The "Generate a .liquidrc file" feature is genius.

Asciidoc support

I am using liquid to generate asciidoc content in a reporting system.

Would it be possible to support asciidoc / liquid combination as well?

Format key binding conflicts with default key binding on Mac.

On a Mac, VSCode maps Cmd+Shift+L to Select All Occurrences of Find Match by default. This plugin overwrites Cmd+Shift+L to Liquid: Format Document which is very degenerative to the UX. Any plugin should not overwrite any of the default key bindings in VSCode. Please consider remapping to another key combination or add editorLangId == 'liquid' to the key binding condition.

Error when doing the quickstart

When I follow the quickstart, and try to run Liquid: Generate .liquidrc File I get the following error:

command 'liquid.liquidrc' not found

image

Any idea why this happens, or what I can do to find out?

Formatter removes newlines in a weird way

Hi,

I've just isntalled your extension into VSCode and like how it works so far.
One issue I have is with the formatter with the default settings -> it removes my newlines .
Example:

  1. code
{%- comment -%}
make sure this file does not have any additional new lines in it. it would break calss generation

assumed variables:
- genClass
- genAdditionalClass
- genSectionClass
- genUseNarrow
{%- endcomment -%}
{%- assign container-classes = bgt-block-h-text-image.container-class | split: ' ' -%}
{%- assign additional-container-classes = additionalContainerClass | split: ' ' -%}
{%- assign containerClass = 'bgt-component-section-h-text-image' -%}
{%- assign isNarrow = true -%}
{%- for class in additional-container-classes -%}
{%- assign containerClass = containerClass | append: ' bgt-component-section-h-text-image--' | append: class -%}
{%- assign containerClass = containerClass | append: ' bgt-component-section--' | append: class -%}
{%- if class == 'edge-to-edge' or class == 'full-width' -%}
{%- assign isNarrow = false -%}
{%- endif -%}
{%- endfor -%}
  1. first save
{% comment %}{%- comment -%}{% endcomment %}
make sure this file does not have any additional new lines in it. it would break calss generation

assumed variables:
- genClass
- genAdditionalClass
- genSectionClass
- genUseNarrow{%- endcomment -%}{%- assign container-classes = bgt-block-h-text-image.container-class | split: ' ' -%}{%- assign additional-container-classes = additionalContainerClass | split: ' ' -%}{%- assign containerClass = 'bgt-component-section-h-text-image' -%}{%- assign isNarrow = true -%}{%- for class in additional-container-classes -%}
{%- assign containerClass = containerClass | append: ' bgt-component-section-h-text-image--' | append: class -%}
{%- assign containerClass = containerClass | append: ' bgt-component-section--' | append: class -%}
{%- if class == 'edge-to-edge' or class == 'full-width' -%}
    {%- assign isNarrow = false -%}
{%- endif -%}{%- endfor -%}
  1. second save
{% comment %}{%- comment -%}{% endcomment %}make sure this file does not have any additional new lines in it. it would break calss generation
    
    assumed variables:
    - genClass
    - genAdditionalClass
    - genSectionClass
    - genUseNarrow{%- endcomment -%}{%- assign container-classes = bgt-block-h-text-image.container-class | split: ' ' -%}{%- assign additional-container-classes = additionalContainerClass | split: ' ' -%}{%- assign containerClass = 'bgt-component-section-h-text-image' -%}{%- assign isNarrow = true -%}{%- for class in additional-container-classes -%}{%- assign containerClass = containerClass | append: ' bgt-component-section-h-text-image--' | append: class -%}{%- assign containerClass = containerClass | append: ' bgt-component-section--' | append: class -%}{%- if class == 'edge-to-edge' or class == 'full-width' -%}
{%- assign isNarrow = false -%}{%- endif -%}{%- endfor -%}

As you can see above, new lines are removed one by one after multiple saves and the code gets minified to some degree. What I want is to automatically indent the code so that I can better follow statements.

I have disabled the formatter as it does not help me at all.

Thanks,
George

Issue with status icon

There is something wrong. When I try click on Enable formating, it shows like it enable but the status do not change.
ezgif-3-1fbb91d547e6

Liquify and the future of this extension!

Hey all users 👋

Firstly, thank you for using this extension. As some of you aware, over the last 12 months I have been working on the next version of this project with the end goal of bringing modern IDE feature to multiple variations of the Liquid Language. This endeavour that has taken a very long time to conclude and this mainly comes down to a few things, like the daily grind of adulthood, work, covid and mostly because Liquid is a customisable language with no real formal grammar, it's a templating language so thats its very nature. Coming up with a solution that will be able to accommodate its various use cases was rather difficult to say the least. Multiple rewrites, lack of sleep and a somewhat steep adoption in new techniques and approaches in software development/engineering etc has resulted in delayed releases.

This issue aims to provide any curious users awaiting on the next release a feature ship list as well as give some insight into what to expect.

Liquify

The next release will be shipping under a new name, which is "Liquify" the reason for this is because support will also be made available in Sublime and Atom. Additionally, the project will open source a multitude of tools and third parties, like its AST parser, TextMate grammars, LSP client and various rollup bundle utilities which are used in the development environment that people may find useful in projects unrelated to the tool.

Variation Specific

Liquify will treat each Liquid Variation differently. Users who are developing with Jekyll do not require Shopify variation features, for example the {% schema %} tag is unique to the Shopify Liquid variation only, it is not available in the Jekyll/Standard/Eleventy variation. The same logic applies to Jekyll/Eleventy where something like frontmatter is not supported in Shopify and therefore users should not be subject to features that are not supported in the development environment they are working within.

In Liquify, you will define your variation on a per-project basis, this will tell the tool to load and execute according to the engine the developer has defined in their .liquidrc file.

Language Server Protocol

Liquify will use the Language Server Protocol (LSP for short) to facilitate its features. LSP is generally leveraged and used by official languages like Python, Elixir, JavaScript and more, so Liquid will be hanging out with the big guys in the code game. More importantly, by leveraging LSP Liquify will become available to any editor that understands the protocol.

Completions

Liquify will provide code completions of tags, objects and filters for multiple variations of Liquid, ie: Shopify, Jekyll, Eleventy etc. Completions will really empower your development workflow, especially for Shopify developers as the entire Shopify theme API will be at your fingertips. For those using Standard Liquid or Jekyll/Eleventy you were not forgotten and completions are facilitated also.

Scope Completions

It's common practice in Liquid to set a variable and then reference that variable or split it up and iterate over the values, whatever the case might be, if you work with this templating language, you're going to use {% assign %} or {% capture %}. Liquify will keep track of your variables, treating them as "scopes" in each file they are defined and from here will automatically be supplied to completions.

Extendable Completions

Completions will be extendable, this means Jekyll/Eleventy developers will be able to provide completions to any custom Liquid tags/filters that you may be implementing through a plugin. You can simply define any extendable completions within the .liquidrc and boom, they are catapulted right into your document tag.

Externally Referenced Completions

Liquid is often referencing data from external files. In Shopify (for example) you will reference locales, or settings_data.json whereas in Jekyll or Eleventy you will reference _collection or _data yaml/json files. In most cases you call upon this data using Liquid and while that has worked just fine for the last decade, the landscape has changed and those files can be monolithic. Services like DatoCMS empower developers by generating these files from a series of models and so it's not always easy remembering what is what. Liquify solves this issue and will scan your workspace for any files that the variation may require or use and from here supply them to you. It does this progressively and will cache results.

This feature may not make it to the official release, but rest assured will be available in a minor post 3.0.

Embedded Language Completions

The completion feature goes one step further by providing embedded language support for code blocks like the Shopify {% schema %} tag where the contained JSON will support completions (so no more shitty or otherwise annoying snippet patches, hooray!) – Embedded language completions use Language Services made available by vscode and you will able to assert new embedded language blocks to specific tags, truly customisable.

Hover Descriptives

Liquify will provide users with hover descriptives of syntax, this means you will never have to goto a documentation page again. The tool will provide you with the official description of each object, object property, tag, or filter relative to the variation it belongs to. This feature will really help devs leverage the language to its fullest and use aspects and tags that you might otherwise not have known existed.

Validations/Linting

Liquify will support syntax validations and linting capabilities. This is a great feature that not only helps you write clean and concise Liquid code, but also will prevent you from writing incorrect syntax. Even though Liquid is a very basic and simple language, it can sometimes get quite chaotic in large code bases and scouring code for parse issues can get tiresome. This feature aims to prevent this and enables you or your team to implement a strict styleguide of how Liquid syntax should be expressed, while at the same automatically fixing errors that may occur.

Users will have the option to control linting via the available rulesets, which can be customized to suit your desired tastes. Want auto-spacing within tags? No problem. Want enforce {% capture %} only variables, No problem. Whatever the case, you will get control via the rulesets.

Codelens / Document Linking

In variations outside of the Standard variation, we have {% include %} (or {% render %} in Shopify) tags which allow developers to reference an external file, otherwise known as snippets or partials. Liquify understands these type of tags and will provide a document link to the file that is being referenced, think of this like import in JavaScript. Simply, cmd+click to open the linked file or peek the content of the include via codelens. Its dope fam, really dope.

Formatting

A lot of developers use this extension for the formatting capabilities, you'll get that goodness in Liquify and it's a lot more powerful. All issues relating to the formatting have been addressed accordingly and by adopting LSP along with the the powerful Liquify AST parser, formatting is far less error prone and won't mess up your code like it has a habit of doing at times. It is still powered with PrettyDiff but now relies more on Sparser. Because Liquid is almost always infused with HTML, rulesets and formatting options are now geared towards a structure and default that is more suitable to a Liquid use case, with indented attribute wrapping/ordering and much more.

Digesting Prettier/JS Beautify

Post Liquify release, the ability to digest prettier/js beautify rules will be made available, this is because PrettyDiff is capable of understanding formatting rulesets supplied by these formatters. This means if you're fanboy or fangirl of those tools, Liquify will respect your presets in those files and work with them to facilitate your beatification taste.

No more injection grammars

In the current version (2.3) grammar injections are leveraged so as to provide and respect HTML Language features like HTML completions and validation supported in vscode. This comes at a cost which I was unaware of when first implementing them and this has led to some errors and headaches. In Liquify, grammar injections have been boycotted but HTML language features have been preserved, this means that Liquid will not interfere with HTML syntax, instead Liquid and HTML are combined and work with one another. I want to apologize to anyone that suffered at that really terrible implementation of mine, I was young and reckless. The new approach will be tightly coupled with variation specific Liquid and Liquify users will get each variation supplied to them as separate languages, for example Liquify will provide:

  • Liquid Standard
  • Liquid Shopify
  • Liquid Jekyll
  • Liquid Eleventy

You will need to choose what variation and grammar to use, opposed to the current approach of selecting HTML. This also means a separation of syntax highlighting specific to the variation you're working with, happy days!

Improved Syntax Highlighting

Liquify has gone a level deeper to bring more expressive syntax highlighting to your editor, you will get even more clear and precise highlighting of code, which allows to you better distinguish Liquid from HTML or other languages, additionally, some great improvements were made to structure of textmate files, which improved rendering speed.

Freemium Model

Liquify will operate on a freemium license model, which means it will be partially proprietary, but chill fam, before you bring upon the wrath of cancel culture, hear me out. Firstly, I am not going to hustle you and all the features you have in the current version are still going to be available in Liquify for free and will forever stay that way. Additionally, most of the features listed here are available for free too. There will be no annoying distractions, popups or "buy me, buy me" bullshit like we all have suffered at the hands of other tech tooling. The extension will function uninterrupted without licensing and again to reiterate the vast majority of features will be free, however some features if you so happen to want them will require a small one-time licensing cost or if you only need to use those features for a project, then you will be able to lease them on a per month basis.

Alight, how much?
Currently, I am still working on the intricacies of this, as of now, licensing will be required for features which pertain to the SaaS variations (ie: Shopify) and/or for some advanced features that pertain to non-SaaS variations – to be clear this still being decided, but please note that individuals and agencies will be subject to different pricing. In terms of cost, for individuals who wants to lease, it will be around the same price as a decent coffee and for the bandits who want to license up, then you will be looking at around the same cost as paperback book. This will be a one time cost, so no ongoing or yearly commitments, you pay, you get, signed sealed delivered.

Any chance it won't ship proprietary
There is still a chance that the tool will ship free with no cost and I really hope that it comes to fruition, fingers crossed!

Conclusion

I've listed the main features you will expect to see in Liquify and I hope anyone that was curious gets a little more insight. There are a lot more great additions shipping, things like .liquidrc intellisense, an optional theme, semantic highlighting, inline comment ignores & formatting, improved support when using Liquid in JavaScript, CSS, SCSS, Markdown, various extensibility, incremental parsing and much more.

The official release is getting closer. To give an ETA is still hard but users can rest easy knowing that it should conclude and go out well before we close this shitty year of 2020, so in the next few months you can expect to be using Liquify.

Thanks,
Panoply.

can't handle objects inserted in style attributes.

The extension will create a error for this line of code even though it's valid, it does not recognize the object. this snippet is from the Dawn 2.0 template, snipppets/product-card.liquid file.

{% if media_size == 'adapt' and product_card_product.featured_media %} style="padding-bottom: {{ 1 | divided_by: featured_media_aspect_ratio | times: 100 }}%;"{% endif %}

Image of errors.
errors

Can't enable extension in VS Code

I'm unable to enable the liquid extension after installing. Tried to install via marketplace but was unable so it prompted me to install manually.

The app is installed but grayed out and I cannot enable for some reason.

Any ideas?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.