vscode-liquid icon indicating copy to clipboard operation
vscode-liquid copied to clipboard

Weird schema formatting

Open stressed-pet-owner opened this issue 2 years ago • 22 comments

On save the schema looks like this. Is this correct? image

Here's my .liquidrc settings { "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, "format_array": "indent", "braces": true, "no_semicolon": true, "brace_block": false } }

stressed-pet-owner avatar Mar 17 '22 05:03 stressed-pet-owner

Hey @stressed-pet-owner

interesting, can you show me the Liquid file?

panoply avatar Mar 17 '22 18:03 panoply

@stressed-pet-owner For some reason you need to add a blank/new line under the {% endschema %} for it to format correctly. Hope this helps!

zayne-anthony avatar Mar 27 '22 15:03 zayne-anthony

I have same problem. plz fix someone :-(

S-kosuke030 avatar Apr 12 '22 06:04 S-kosuke030

I am having a similar problem. schema JSON in sections format in a bad way. image I tried using the default .liquidrc and then for testing just inserted it into my workspace settings file. .vscode/settings.json

{
  "editor.formatOnSave": true,
  // Controls whether formatting is enabled or disabled
  "liquid.format": true,
  // Formatting code style rules
  "liquid.rules": {
    "ignore": [
      {
        "type": "liquid",
        "begin": "comment",
        "end": "endcomment"
      },
      {
        "type": "liquid",
        "begin": "schema",
        "end": "endschema"
      },
      {
        "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,
      "format_array": "indent",
      "braces": true,
      "no_semicolon": true,
      "brace_block": false
    }
  }
}

Any ideas how to fix this?

3daddict avatar Apr 14 '22 04:04 3daddict

Add this to a .liquidrc file (this is my defaults, tends to work for most use cases)

{
  "ignore": [
    {
      "type": "liquid",
      "begin": "comment",
      "end": "endcomment"
    },
    {
      "type": "liquid",
      "begin": "capture",
      "end": "endcapture"
    }
  ],
  "html": {
    "correct": true,
    "force_attribute": false,
    "braces": false,
    "preserve": 1,
    "wrap": 85,
    "preserve_text": true,
    "content": true,
    "space_close": true,
    "tags": [
      {
        "tag": "source",
        "rules": {
          "force_attribute": true,
          "space_close": true
        }
      }
    ]
  },
  "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": true,
    "brace_block": false,
    "no_semicolon": true
  }
}

Try using the .liquidrc file over the vscode preference settings. In your preference (or workspace) settings have the following configuration.

Preferably just apply these within your workspace settings (ie: within a .vscode/settings.json) at the root of your project.

 "liquid.format": true,
  "files.associations": {
    "*.liquid": "html"
  },
 "[html]": {
    "editor.defaultFormatter": "sissel.shopify-liquid"
  }

Lastly and most importantly. Make sure you are not using Prettier in combination with the extension and formatting HTML or markup languages. The simplest thing to do is just exclude directories of .liquid files in a .prettierignore - Typically, this is going to cause the issues.

For example, using your directory structure @3daddict you'd do the following in a .prettierignore file:

src/components/sections

In some situations you just simply need to restart vscode because the diffing engine will have a cache used by Sparser.

panoply avatar Apr 14 '22 04:04 panoply

Thanks @panoply things are looking much better, especially html elements.

  1. Added your .liquidrc
  2. Updated settings.json with your snippet.
  3. Added *.liquid to .prettierignore

Is it possible to get the schema to format the JSON? image

The updates have successfully ignored auto-formatting in schema but is there a way to actually have that format on save as well? Thanks for this info I learned a lot!

3daddict avatar Apr 14 '22 05:04 3daddict

I'm not sure why formatting is failing within your code. For some context, here is screencast of formatting working on a very large section. Try the following:

  1. Remove the code within the {% schema %} and then restart your editor. Then begin writing it again.
  2. Check you do not have any additional Liquid configs within your user settings.
  3. Double check you do not have additional extensions running that are intercepting the markup.

https://user-images.githubusercontent.com/7041324/163325173-5b5d3789-66b8-4634-949f-5c821df0ba93.mov

panoply avatar Apr 14 '22 06:04 panoply

Formatting is intended to work on document save, here are some additional configs that might help you:

"editor.foldingStrategy": "indentation",
"editor.formatOnSave": true

The updates have successfully ignored auto-formatting in schema but is there a way to actually have that format on save as well?

Just incase you forgot, if you have set the {% schema %} to ignore, then you will need to remove it for the formatting to work 😉

panoply avatar Apr 14 '22 06:04 panoply

@panoply I don't think I am ignoring schema in my setup.

On save only the {% endschema %} moves and not the json.

https://user-images.githubusercontent.com/29803478/163420214-e524799e-6d08-42fe-9e91-87d043f8e0e5.mov

I tried removing all prettier settings and it still behaved the same way. This one has me stumped. I can't seem to find that one setting that might control this schema json.

3daddict avatar Apr 14 '22 15:04 3daddict

Hi @panoply, I was able to solve for the issue above with the following rule on the json in the .liquidrc

  "json": {
    "preserve": 0,
    "braces": true,
    "brace_block": false,
    "no_semicolon": true,
    "tags": [
      {
        "type": "liquid",
        "begin": "schema",
        "end": "endschema"
      }
    ]
  }

I made a public test repo here and I can't seem to figure out the formatting rules to get JSON+LD looking correctly. Adding this tag in the json rule in the .liquidrc fixed the json breaking on format

 "tags": [
      {
        "type": "html",
        "begin": "script type=\"application/ld+json\"",
        "end": "script"
      }
    ]

But there are still some formatting issues when it comes to liquid inside the json

https://user-images.githubusercontent.com/29803478/163918482-b80f2b68-21cf-4dd8-b1bf-6f5769b9c3eb.mov

Any ideas on how one would create a rule for liquid inside json?

3daddict avatar Apr 19 '22 04:04 3daddict

Search the issues regarding this. I posted an solution somewhere.

Sent from my iPhone

On 19 Apr 2022, at 06:21, Mike @.***> wrote:

 Hi @panoply, I was able to solve for the issue above with the following rule on the json in the .liquidrc

"json": { "preserve": 0, "braces": true, "brace_block": false, "no_semicolon": true, "tags": [ { "type": "liquid", "begin": "schema", "end": "endschema" } ] } I made a public test repo here and I can't seem to figure out the formatting rules to get JSON+LD looking correctly. Adding this tag in the json rule in the .liquidrc fixed the json breaking on format

"tags": [ { "type": "html", "begin": "script type="application/ld+json"", "end": "script" } ] But there are still some formatting issues when it comes to liquid inside the json

https://user-images.githubusercontent.com/29803478/163918482-b80f2b68-21cf-4dd8-b1bf-6f5769b9c3eb.mov

Any ideas on how one would create a rule for liquid inside json?

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.

panoply avatar Apr 19 '22 09:04 panoply

@3daddict also, your issues are likely to do with a third party extension. You should not have to add the schema tag. Disable other extensions and figure out the conflict.

panoply avatar Apr 19 '22 09:04 panoply

Thanks @panoply

{% assign attr = 'type="application/ld+json"' %}

<script {{ attr }}>
  {
    "name": "foo",
    "settings": [
      {
        "type": "something"
      }
    ]
  }
</script>

Seems to be a good temp solution but even after disabling all extensions that might format it still doesn't look right for me when it comes to liquid conditions. I'll keep an eye out on issue #38 for any future updates. Thanks for all the help here!

{% assign attr = 'type="application/ld+json"' %}
<script {{ attr }}>
  {
    "@context": "http://schema.org/BlogPosting",
    "@type": "BlogPosting",
    "headline": {{ article.title | json }},
    "articleBody": {{ article.content | strip_html | json }},{%- if article.exerpt != blank -%}
      "description" : {{ article.exerpt | strip_html | json }},{%- endif -%}
    {%- if article.image -%}
      "image" : [{{ article.image | img_url: "medium" | prepend: 'https:' | json }}],{%- endif -%}
    "datePublished": {{ article.published_at | date: format: "default" | json }},
    "dateCreated": {{ article.created_at | date: format: "default" | json }},
    "author": {
      "@type": "Person",
      "name": {{ article.author | json }}
    },
    "publisher": {
      "@type": "Organization",
      "name": {{ shop.name | json }}
    }
  };
</script>

@stressed-pet-owner hopefully these thread updates help you solve your issue.

3daddict avatar Apr 19 '22 16:04 3daddict

Hey @3daddict - following your steps just results in an error:

CleanShot 2022-04-20 at 10 46 59

ANy ideas?

joelwmale avatar Apr 20 '22 00:04 joelwmale

@joelwmale what steps are you following? From the image above it looks like you need to configure your default formatter in VS code. Are you working off my test repo?

3daddict avatar Apr 20 '22 01:04 3daddict

@joelwmale follow https://github.com/panoply/vscode-liquid/issues/86#issuecomment-1098703275

@3daddict the reason it gets messed up is because you cannot infuse Liquid and JSON together. The formatter only supports Liquid + HTML. Even though Shopify "experts" tend to leverage Liquid in such a manner (ie: combine it into JSON, CSS, JavaScript etc) that practice in itself generally leads to terrible and unreadable code.

I have solved a large portion of the formatting issues in Prettify but there is still edge-cases that need work and I am doing 19 hours days atm for my job.


You can avoid a lot formatting issues by re-thinking the approaches you take when using Liquid. For example, when it comes to JSON like the code example you shared (ld+json) the internal parser is interpreting curly braces, eg {{ }} as objects resulting in your code not formatting correctly.

You can negate and avoid that by simply ensuring you enclose Liquid objects, eg: ({{ }}) or tags ({% %}) in quotation characters, see below:

<script type="{{ 'application/ld+json' }}">
  {
  "@context": "http://schema.org/",
  "@type": "Product",
  "@id": "{{ shop.url | append: '/products/' | append: product.handle }}",
  "url": "{{ shop.url | append: '/products/' | append: product.handle }}",
  "name": "{{ product.title }}",
  "image": "{{ product.featured_image.src | img_url: 'master' }}",
  "description": "{{ product.description | strip_html | strip_newlines | escape }}",
  "brand": {
    "name": "{{ product.vendor }}"
  },
  "offers": {
    "@type": "Offer",
    "priceCurrency": "{{ shop.currency }}",
    "price": "{{ product.selected_or_first_available_variant.price | money_without_currency }}",
    "availability": "http://schema.org/{% if product.available %}InStock{% else %}OutOfStock{% endif %}",
    "seller": {
      "@type": "Organization",
      "name": "{{ shop.name }}"
    }
  }
}
</script>

Notice how all Liquid code is enclosed in strings? the formatter will have no issues with such code. When it comes to reaching for {{ foo | json }} json filters not only is it a perf hit but the way in which Shopify outputs JSON is not really ideal, to avoid that, just be more explicit and construct the entire object. Also, no matter how many settings you try, conditional (ie: {% if %} etc) will always break when contained in languages outside of HTML, which means you can't drop it into JSON like you have and expect it to behave, well at least not the version the extension is running and not even in Prettify have I been able to solve this.

Example of tame structures

Take the following section I have extracted from a project I developed. I picked this section cause it will do a good job of helping those approach these things with a little more direction. Notice how within this section I am not reaching for <style></style> tags nor am I using {% script %} or {% style %} liquid tags.

Instead, I use a JavaScript framework to avoid having to use {% script %} tags and all the data I require is passed in via attributes. When it comes to applying custom styles and such I am inlining them using style="" attributes and taking advantage of CSS variables. The reason I am using {% capture %} is because its faster than {% assign %} and it allows me to have a clear oversight of the code.

The section and Liquid is tame and I don't expect everyone to code or adopt my styles but do think it is worth noting that because Shopify does things a certain way in Dawn does not mean it is the right way. So when it comes to your JSON+LD schema tag the Dawn way will not work seamlessly with the formatter of the extension.

{%- comment -%}

  HERO SLIDESHOW

  Renders a carousel slideshow components
  that can contain image or video content.
  Each slide can apply text overlay content
  identical to that of which can be set in
  the hero_image section. Single slides are
  enforced on the carousel.

{%- endcomment -%}
<div
  class="hero col mt-{{ section.settings.mt }} mb-{{ section.settings.mb }}"
  data-controller="carousel"
  data-carousel-hydrate-value="true"
  data-carousel-mobile-value="1"
  data-carousel-tablet-value="1"
  data-carousel-desktop-value="1"
  data-carousel-id-value=" {{- section.id | base64_encode }}"
  data-carousel-loop-value=" {{- section.settings.loop }}"
  data-carousel-draggable-value=" {{- section.settings.draggable }}"
  data-carousel-duration-value=" {{- section.settings.duration }}"
  data-carousel-interval-value=" {{- section.settings.interval }}">

  {%- if section.settings.buttons -%}
    <div class="previous d-flex ai-center">
      <button aria-label="Previous" data-action="click->carousel#prev" type="button">
        <icon name="chevron-left" />
      </button>
    </div>
    <div class="next d-flex ai-center">
      <button aria-label="Next" data-action="click->carousel#next" type="button">
        <icon name="chevron-right" />
      </button>
    </div>
  {%- endif -%}

  <div data-carousel-target="siema">

    {%- for block in section.blocks -%}

      {%- assign item = block.settings -%}

      <div
        class=" {%- unless forloop.first %}col px-0 d-none{% else %}col px-0{% endunless %}"
        data-carousel-target="slide">

        {%- if block.type == 'image_with_content' -%}

          {%- capture spacing -%}
            mb-{{- item.py_mobile }}
            mb-sm-{{- item.py_desktop }}
          {%- endcapture -%}

          {%- capture gutter -%}
            px-{{- item.mx_mobile }}
            py-{{- item.my_mobile }}
            px-sm-{{- item.mx_desktop }}
          {%- endcapture -%}

          <div class="hero-caption d-flex p-3 p-sm-5 {{ item.pos_mobile }} {{ item.pos_desktop }}">
            <div class="{{ gutter }} py-sm-{{ item.my_desktop }} {{ item.ta_mobile }} {{ item.ta_desktop }}">

              {%- if item.title != blank -%}

                {%- capture styles -%}
                  color:{{- item.title_fc | default: 'inherit' -}};
                  letter-spacing:{{- item.title_ls | default: 'inherit' -}}px;
                  font-size:{{- item.title_fs | default: 'inherit' -}}px;
                  font-weight:{{- item.title_fw | default: 'inherit' -}};
                {%- endcapture -%}

                <h1 class="{{ spacing }}" style="{{ styles }}">
                  {{- item.title -}}
                </h1>

              {%- endif -%}

              {%- if item.subtitle != blank -%}

                {%- capture style -%}
                  color:{{- item.subtitle_fc | default: 'inherit' -}};
                  letter-spacing:{{- item.subtitle_ls | default: 'inherit' -}}px;
                  font-size:{{- item.subtitle_fs | default: 'inherit' -}}px;
                  font-weight:{{- item.subtitle_fw | default: 'inherit' -}};
                {%- endcapture -%}

                <h1 class="{{ spacing }}" style="{{ style }}">
                  {{- item.subtitle -}}
                </h1>

              {%- endif -%}

              {%- if item.caption != blank -%}

                {%- capture style -%}
                  color:{{- item.caption_fc | default: 'inherit' -}};
                  letter-spacing:{{- item.caption_ls | default: 'inherit' -}}px;
                  font-size:{{- item.caption_fs | default: 'inherit' -}}px;
                  font-weight:{{- item.caption_fw | default: 'inherit' -}};
                  max-width:{{- item.caption_width -}}px;
                  {%- if item.caption_lh != 0 -%}
                  line-height:{{- item.caption_lh -}}px;
                  {%- endif -%}
                {%- endcapture -%}

                <p class="{{ spacing }}" style="{{ style }}">
                  {{- item.caption | remove: '<p>' | remove: '</p>' -}}
                </p>

              {%- endif -%}

              {%- if item.btn != blank -%}

                {%- capture style -%}
                  color:{{- item.btn_fc | default: 'inherit' -}};
                  background-color:{{- item.btn_bg | default: 'inherit' -}};
                  font-size:{{- item.btn_fs | default: 'inherit' -}}px;
                  font-weight:{{- item.btn_fw | default: 'inherit' -}};
                  height:{{- item.btn_height }}px;
                  max-width:{{- item.btn_width }}px;
                {%- endcapture -%}

                {%- capture class -%}
                  {%- if item.btn_radius and item.btn_shadow -%}
                    btn-radius btn-shadow mt-{{ item.btn_mt }}
                  {%- elsif item.btn_shadow -%}
                    btn-shadow mt-{{ item.btn_mt }}
                  {%- elsif item.btn_radius -%}
                    btn-radius mt-{{ item.btn_mt }}
                  {%- else -%}
                    mt-{{ item.btn_mt }}
                  {%- endif -%}
                {%- endcapture -%}

                <a href="{{ item.url }}" style="{{ style }}" class="btn btn-line {{ class }}">
                  {{- item.btn -}}
                </a>

              {%- endif -%}

            </div>
          </div>
        {%- endif -%}

        {%- unless block.type contains 'video' -%}

          {%- capture aspect_ratio -%}
            --ratio-width:{{- item.img_desktop.width -}};
            --ratio-height:{{- item.img_desktop.height -}};
            --ratio-width-sm:{{- item.img_mobile.width -}};
            --ratio-height-sm:{{- item.img_mobile.height -}};
          {%- endcapture -%}

          <div class="aspect-ratio" style="{{ aspect_ratio }}">
            {%- if item.img_desktop != blank and item.img_mobile != blank -%}
              <picture>
                <source
                  media="lg"
                  data-srcset="{{ item.img_desktop | img_url: '1440x' | format: 'pjpg' }}" />
                <source
                  media="md"
                  data-srcset="{{ item.img_desktop | img_url: '1240x' | format: 'pjpg' }}" />
                <source
                  media="sm"
                  data-srcset="{{ item.img_mobile | img_url: '1024x' | format: 'pjpg' }}" />
                <source
                  media="xs"
                  data-srcset="{{ item.img_mobile | img_url: '1024x' | format: 'pjpg' }}" />
                <img
                  class="img-fluid lazy"
                  data-src=" {{- item.img_desktop | img_url: '1440x' | format: 'pjpg' }}">
              </picture>
            {%- else -%}
              {%- render 'placeholder', type: 'hero_image' -%}
            {%- endif -%}
          </div>
        {%- endunless -%}
      </div>
    {%- endfor -%}
  </div>
</div>

{% schema %}
{
  "name": "Hero Slideshow",
  "tag": "section",
  "class": "row jc-center ai-center",
  "blocks": [
    {
      "type": "image",
      "name": "Image",
      "settings": [
        {
          "type": "header",
          "content": "Link",
          "info": "Renders a href link on the hero image"
        },
        {
          "type": "url",
          "id": "href",
          "label": "Link"
        },
        {
          "type": "header",
          "content": "Images",
          "info": "Choose or upload desktop and mobile images"
        },
        {
          "type": "image_picker",
          "id": "img_desktop",
          "label": "Desktop Image",
          "info": "Dimensions: 1440x"
        },
        {
          "type": "image_picker",
          "id": "img_mobile",
          "label": "Mobile Image",
          "info": "Dimensions: 1024x1024"
        }
      ]
    },
    {
      "type": "image_with_content",
      "name": "Image with Content",
      "settings": [
        {
          "type": "header",
          "content": "Desktop Layout",
          "info": "Controls the viewport content position and text alignment"
        },
        {
          "type": "select",
          "id": "pos_desktop",
          "label": "Desktop Position",
          "default": "jc-sm-center ai-sm-center",
          "options": [
            {
              "value": "jc-sm-start ai-sm-start",
              "label": "Top Left"
            },
            {
              "value": "jc-sm-center ai-sm-start",
              "label": "Top Center"
            },
            {
              "value": "jc-sm-end ai-sm-start",
              "label": "Top Right"
            },
            {
              "value": "jc-sm-start ai-sm-center",
              "label": "Middle Left"
            },
            {
              "value": "jc-sm-center ai-sm-center",
              "label": "Middle Center"
            },
            {
              "value": "jc-sm-end ai-sm-center",
              "label": "Middle Right"
            },
            {
              "value": "jc-sm-start ai-sm-end",
              "label": "Bottom Left"
            },
            {
              "value": "jc-sm-center ai-sm-end",
              "label": "Bottom Center"
            },
            {
              "value": "jc-sm-end ai-sm-end",
              "label": "Bottom Right"
            }
          ]
        },
        {
          "type": "select",
          "id": "ta_desktop",
          "label": "Text Alignment",
          "default": "text-sm-center",
          "options": [
            {
              "value": "text-sm-left",
              "label": "Left"
            },
            {
              "value": "text-sm-center",
              "label": "Center"
            },
            {
              "value": "text-sm-right",
              "label": "Right"
            }
          ]
        },
        {
          "type": "range",
          "id": "mx_desktop",
          "label": "Gutters X",
          "info": "The X (left and right) spacing gutters surrounding the content",
          "min": 0,
          "max": 5,
          "step": 1,
          "default": 2
        },
        {
          "type": "range",
          "id": "my_desktop",
          "label": "Gutters Y",
          "info": "The Y (top and bottom) spacing gutters surrounding the content",
          "min": 0,
          "max": 5,
          "step": 1,
          "default": 2
        },
        {
          "type": "range",
          "id": "py_desktop",
          "label": "Spacing",
          "info": "The inner Y spacing between each text element",
          "min": 1,
          "max": 5,
          "step": 1,
          "default": 2
        },
        {
          "type": "header",
          "content": "Mobile Layout",
          "info": "Controls the viewport content position and text alignment. This is optional if no settings are defined options will inherit desktop definitions."
        },
        {
          "type": "select",
          "id": "pos_mobile",
          "label": "Mobile Position",
          "default": "jc-center ai-center",
          "options": [
            {
              "value": "jc-start ai-start",
              "label": "Top Left"
            },
            {
              "value": "jc-center ai-start",
              "label": "Top Center"
            },
            {
              "value": "jc-end ai-start",
              "label": "Top Right"
            },
            {
              "value": "jc-start ai-center",
              "label": "Middle Left"
            },
            {
              "value": "jc-center ai-center",
              "label": "Middle Center"
            },
            {
              "value": "jc-end ai-center",
              "label": "Middle Right"
            },
            {
              "value": "jc-start ai-end",
              "label": "Bottom Left"
            },
            {
              "value": "jc-center ai-end",
              "label": "Bottom Center"
            },
            {
              "value": "jc-end ai-end",
              "label": "Bottom Right"
            }
          ]
        },
        {
          "type": "select",
          "id": "ta_mobile",
          "label": "Text Alignment",
          "default": "text-center",
          "options": [
            {
              "value": "text-left",
              "label": "Left"
            },
            {
              "value": "text-center",
              "label": "Center"
            },
            {
              "value": "text-right",
              "label": "Right"
            }
          ]
        },
        {
          "type": "range",
          "id": "mx_mobile",
          "label": "Gutters X",
          "info": "The X (left and right) spacing gutters surrounding the content",
          "min": 0,
          "max": 5,
          "step": 1,
          "default": 2
        },
        {
          "type": "range",
          "id": "my_mobile",
          "label": "Gutters Y",
          "info": "The Y (top and bottom) spacing gutters surrounding the content",
          "min": 0,
          "max": 5,
          "step": 1,
          "default": 2
        },
        {
          "type": "range",
          "id": "py_mobile",
          "label": "Spacing",
          "info": "The inner Y spacing between each text element",
          "min": 1,
          "max": 5,
          "step": 1,
          "default": 2
        },
        {
          "type": "header",
          "content": "Title",
          "info": "Define a title text overlay to the image."
        },
        {
          "type": "text",
          "id": "title",
          "label": "Title"
        },
        {
          "type": "color",
          "label": "Font Colour",
          "id": "title_fc"
        },
        {
          "type": "range",
          "id": "title_fs",
          "label": "Font Size",
          "min": 1,
          "max": 50,
          "step": 0.5,
          "default": 15,
          "unit": "px"
        },
        {
          "type": "range",
          "id": "title_ls",
          "label": "Letter Spacing",
          "min": 0.1,
          "max": 3,
          "step": 0.1,
          "default": 0.5,
          "unit": "px"
        },
        {
          "type": "range",
          "id": "title_fw",
          "label": "Font Weight",
          "min": 100,
          "max": 600,
          "step": 100,
          "default": 300
        },
        {
          "type": "header",
          "content": "Subtitle",
          "info": "Define a subtitle text overlay to the image."
        },
        {
          "type": "text",
          "id": "subtitle",
          "label": "Subtitle"
        },
        {
          "type": "color",
          "label": "Font Colour",
          "id": "subtitle_fc"
        },
        {
          "type": "range",
          "id": "subtitle_fs",
          "label": "Font Size",
          "min": 1,
          "max": 50,
          "step": 0.5,
          "default": 15,
          "unit": "px"
        },
        {
          "type": "range",
          "id": "subtitle_ls",
          "label": "Letter Spacing",
          "min": 0.1,
          "max": 3,
          "step": 0.1,
          "default": 0.5,
          "unit": "px"
        },
        {
          "type": "range",
          "id": "subtitle_fw",
          "label": "Font Weight",
          "min": 100,
          "max": 600,
          "step": 100,
          "default": 300
        },
        {
          "type": "header",
          "content": "Caption",
          "info": "Define a caption text overlay to the image"
        },
        {
          "type": "textarea",
          "id": "caption",
          "label": "Description"
        },
        {
          "type": "color",
          "label": "Font Colour",
          "id": "caption_fc"
        },
        {
          "type": "range",
          "id": "caption_fs",
          "label": "Font Size",
          "min": 1,
          "max": 50,
          "step": 0.5,
          "default": 15,
          "unit": "px"
        },
        {
          "type": "range",
          "id": "caption_ls",
          "label": "Letter Spacing",
          "min": 0.1,
          "max": 3,
          "step": 0.1,
          "default": 0.5,
          "unit": "px"
        },
        {
          "type": "range",
          "id": "caption_lh",
          "label": "Line Height",
          "info": "Use a 0 value for default",
          "min": 0,
          "max": 50,
          "step": 0.5,
          "default": 0,
          "unit": "px"
        },
        {
          "type": "range",
          "id": "caption_fw",
          "label": "Font Weight",
          "min": 100,
          "max": 600,
          "step": 100,
          "default": 300
        },
        {
          "type": "range",
          "id": "caption_width",
          "label": "Width",
          "info": "The maximum width which contains the caption text",
          "unit": "px",
          "min": 0,
          "max": 1000,
          "step": 50,
          "default": 300
        },
        {
          "type": "header",
          "content": "Button",
          "info": "Add a button to the content overlay"
        },
        {
          "type": "text",
          "id": "btn",
          "label": "Label"
        },
        {
          "type": "url",
          "id": "btn_url",
          "label": "Link"
        },
        {
          "type": "color",
          "label": "Text Colour",
          "id": "btn_fc"
        },
        {
          "type": "color",
          "label": "Button Background",
          "id": "btn_bg"
        },
        {
          "type": "checkbox",
          "id": "btn_shadow",
          "label": "Button Shadow",
          "default": true
        },
        {
          "type": "checkbox",
          "id": "btn_radius",
          "label": "Button Radius",
          "default": true
        },
        {
          "type": "range",
          "id": "btn_width",
          "label": "Button Width",
          "min": 10,
          "max": 250,
          "step": 5,
          "default": 100,
          "unit": "px"
        },
        {
          "type": "range",
          "id": "btn_height",
          "label": "Button Height",
          "min": 10,
          "max": 100,
          "step": 1,
          "default": 25
        },
        {
          "type": "range",
          "id": "btn_fs",
          "label": "Font Size",
          "min": 1,
          "max": 30,
          "step": 0.5,
          "default": 15,
          "unit": "px"
        },
        {
          "type": "range",
          "id": "btn_fw",
          "label": "Font Weight",
          "min": 100,
          "max": 600,
          "step": 100,
          "default": 300
        },
        {
          "type": "range",
          "id": "btn_mt",
          "label": "Gutter Top",
          "min": 0,
          "max": 5,
          "step": 1,
          "default": 3
        },
        {
          "type": "header",
          "content": "Link",
          "info": "Make the image a link"
        },
        {
          "type": "url",
          "id": "href",
          "label": "Link"
        },
        {
          "type": "checkbox",
          "id": "href_btn",
          "label": "Button Precedence",
          "info": "Whether or not to disable if button links are defined",
          "default": true
        },
        {
          "type": "header",
          "content": "Images",
          "info": "Choose or upload desktop and mobile images"
        },
        {
          "type": "image_picker",
          "id": "img_desktop",
          "label": "Desktop Image",
          "info": "Dimensions: 1440x"
        },
        {
          "type": "image_picker",
          "id": "img_mobile",
          "label": "Mobile Image",
          "info": "Dimensions: 1024x1024"
        }
      ]
    }
  ],
  "settings": [
    {
      "type": "header",
      "content": "Gutters",
      "info": "Applies gutter margins to the section layout"
    },
    {
      "type": "range",
      "id": "mt",
      "label": "Gutter Top",
      "min": 0,
      "max": 5,
      "step": 1,
      "default": 2
    },
    {
      "type": "range",
      "id": "mb",
      "label": "Gutter Bottom",
      "min": 0,
      "max": 5,
      "step": 1,
      "default": 2
    },
    {
      "type": "header",
      "content": "Carousel",
      "info": "Control settings for the carousel component"
    },
    {
      "type": "checkbox",
      "id": "loop",
      "label": "Loop",
      "default": false
    },
    {
      "type": "checkbox",
      "id": "draggable",
      "label": "Draggable",
      "default": true
    },
    {
      "type": "checkbox",
      "id": "buttons",
      "label": "Show Buttons",
      "default": true
    },
    {
      "type": "range",
      "id": "interval",
      "label": "Interval (Autoplay)",
      "info": "The autoplay interval timing, use a value of 0 to disable.",
      "unit": "ms",
      "min": 0,
      "max": 9000,
      "step": 100,
      "default": 0
    },
    {
      "type": "range",
      "id": "duration",
      "label": "Duration",
      "info": "The slide animation duration",
      "unit": "ms",
      "min": 100,
      "max": 1000,
      "step": 50,
      "default": 300
    }
  ],
  "presets": [
    {
      "name": "Hero Slideshow",
      "category": "Image"
    }
  ]
}
{% endschema %}

I know this is going off topic here but hopefully it gives you a better understanding. While I understand things should just work, the extension was never really developed for so many users. You can take a peak at #56 and see what I have been able to get through the last few years with this specific project and while it doesn't solve your issues, it gives some light at the end of the tunnel.

panoply avatar Apr 20 '22 02:04 panoply

@3daddict Also, here is how you should write it:

<script {{ 'application/ld+json' }}>
  {
    "@context": "http://schema.org/BlogPosting",
    "@type": "BlogPosting",
    "headline": "{{ article.title }}",
    "articleBody": "{{ article.content | strip_html }}",
    "description": "{{ article.exerpt | strip_html | default: ' ' }}",
    "datePublished": "{{ article.published_at | date: format: 'default' }}",
    "dateCreated": "{{ article.created_at | date: format: 'default' }}",
    "image": [{% if article.image %}"{{ article.image | img_url: 'medium' | prepend: 'https:' }}"{% endif %}],
    "author": {
      "@type": "Person",
      "name": "{{ article.author }}"
    },
    "publisher": {
      "@type": "Organization",
      "name": "{{ shop.name }}"
    }
  };
</script>

panoply avatar Apr 20 '22 02:04 panoply

@panoply thanks for sharing all that info, it's helpful and basically just solved all the trivial issues I was having. Makes total sense and how I need to re-think how and where I am trying to use liquid. I need to use capture way more! The test repo is now formatting perfectly. I am going to make notes from your info above to reference later.

This extension is a huge asset to liquid development and I am excited to see Liquify launch. Thanks for all the help!

3daddict avatar Apr 20 '22 03:04 3daddict

^ Thanks @3daddict, I had issues with the formatter wrapping long schema JSON strings, for whatever reason the settings config from that repo fixed it for me.

For anyone else, the settings JSON that @3daddict is using in the repo linked above:

{
  "editor.foldingStrategy": "indentation",
  "editor.formatOnSave": true,
  "liquid.format": true,
  "files.associations": {
    "*.liquid": "html"
  },
  "[html]": {
    "editor.defaultFormatter": "sissel.shopify-liquid"
  }
}

Previously I had to do

"liquid.rules": {
  "json": {
    "preserve_text": true
  }
},

to fix the Schema JSON string wrapping issue and was manually running "Reindent lines" on the schema.

Christopher-Hayes avatar May 25 '22 21:05 Christopher-Hayes

FWIW this was addressed in Prettify along with descriptive annotation so folks can better understand what each rule does (example) and it will be used under the hood in Liquify.

panoply avatar May 25 '22 23:05 panoply

I just encountered this problem when I'm practicing Liquid. It turns out to be a conflict between Prettier and Liquid extension. As my editor has a default formatter for html specified in default setting.

// (global) settings.json
"[html]": {
   "editor.defaultFormatter": "esbenp.prettier-vscode"
 }

I set up a setting.json file in my root folder and say I'd like to use Liquid to format my code, like the following:

// .vscode/settings.json
{
  "[html]": {
    "editor.defaultFormatter": "sissel.shopify-liquid"
  }
}

and then I create a .liquidrc file and paste the content above the discussion. Magically, the schema is well formatted! Thanks for the support from all you!

apo1798 avatar Jun 16 '22 06:06 apo1798

Have this same issue, anything between schema tags is not indented properly.

hilyin avatar Jun 23 '22 21:06 hilyin

🚢 Shipped v3.0.0

This should no longer be an issue. Take a look at readme and release notes. Also look at Prettify.

panoply avatar Sep 28 '22 08:09 panoply