Skip to content
This repository has been archived by the owner on Jun 20, 2024. It is now read-only.

LiquidHTMLParsingError throws error for <details> tag #213

Closed
mzachdev opened this issue Nov 10, 2023 · 2 comments · Fixed by Shopify/theme-tools#253
Closed

LiquidHTMLParsingError throws error for <details> tag #213

mzachdev opened this issue Nov 10, 2023 · 2 comments · Fixed by Shopify/theme-tools#253
Labels
bug Something isn't working

Comments

@mzachdev
Copy link

mzachdev commented Nov 10, 2023

Describe the bug
The prettier-plugin-liquid throws an error [LiquidHTMLParsingError] on a file from the Impulse theme by Archetype. The HTML tag is closed correctly, it's clearly not able to parse the code properly. The error is thrown specifically for the <details...> tag, which is closed all the way at the bottom of the code block.

Is there a way to disable this error for this file or code block only? I'm unfamiliar with how to do that. Thanks!

Unformatted source

<li class="site-nav__item site-nav__expanded-item{% if has_dropdown %} site-nav--has-dropdown{% endif %}{% if is_megamenu %} site-nav--is-megamenu{% endif %}">
      {% if is_megamenu or has_dropdown %}
        <details
          data-hover="{{ hover_menu }}"
          id="site-nav-item--{{ forloop.index }}"
          class="site-nav__details"
        >
          <summary
            data-link="{{ link.url }}"
            aria-expanded="false"
            aria-controls="site-nav-item--{{ forloop.index }}"
            class="site-nav__link site-nav__link--underline{% if has_dropdown %} site-nav__link--has-dropdown{% endif %}"
          >
            {{ link.title }} <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon--wide icon-chevron-down" viewBox="0 0 28 16"><path d="m1.57 1.59 12.76 12.77L27.1 1.59" stroke-width="2" stroke="#000" fill="none"/></svg>
          </summary>
      {% else %}
        <a
          href="{{ link.url }}"
          class="site-nav__link site-nav__link--underline{% if has_dropdown %} site-nav__link--has-dropdown{% endif %}"
        >
          {{ link.title }}
        </a>
      {% endif %}
        {%- if is_megamenu -%}
          {%- assign previous_column_type = '' -%}
          {%- assign animation_column = 1 -%}

          <div class="site-nav__dropdown megamenu text-left">
            <div class="page-width">
              <div class="grid{% if dropdown_alignment == 'center' %} grid--center{% endif %}">
                <div class="grid__item medium-up--one-fifth appear-animation appear-delay-{{ animation_column }}">
                  {%- assign animation_column = animation_column | plus: 1 -%}

                  {%- for childlink in link.links -%}
                    {%- liquid
                      assign create_new_column = false

                      if childlink.levels > 0 and forloop.index != 1
                        assign create_new_column = true
                      endif

                      if childlink.levels == 0 and previous_column_type == 'full'
                        assign create_new_column = true
                      endif
                    -%}

                    {%- if create_new_column -%}
                      </div><div class="grid__item medium-up--one-fifth appear-animation appear-delay-{{ animation_column }}">
                      {%- assign animation_column = animation_column | plus: 1 -%}
                    {%- endif -%}

                    {%- if childlink.levels > 0 and childlink.url contains '/collections/' -%}
                      {%- if collections[childlink.object.handle].image != blank and section.settings.mega_menu_images -%}
                        <a href="{{ childlink.url }}">
                          <div class="svg-mask svg-mask--landscape">
                          {%- render 'image-element',
                            img: collections[childlink.object.handle].image,
                            sizeVariable: '20vw',
                            alt: collections[childlink.object.handle].title,
                            classes: 'megamenu__collection-image',
                          -%}
                          </div>
                        </a>
                      {%- endif -%}
                    {%- endif -%}

                    <div class="h5">
                      <a href="{{ childlink.url }}" class="site-nav__dropdown-link site-nav__dropdown-link--top-level">{{ childlink.title }}</a>
                    </div>

                    {%- liquid
                      if childlink.levels > 0
                        assign previous_column_type = 'full'
                      else
                        assign previous_column_type = 'single'
                      endif
                    -%}

                    {%- for grandchildlink in childlink.links -%}
                      <div>
                        <a href="{{ grandchildlink.url }}" class="site-nav__dropdown-link">
                          {{ grandchildlink.title }}
                        </a>
                      </div>
                    {%- endfor -%}
                  {%- endfor -%}
                </div>
              </div>
            </div>
          </div>
        {%- elsif has_dropdown -%}
          <ul class="site-nav__dropdown text-left">
            {%- for childlink in link.links -%}
              {%- liquid
                assign has_sub_dropdown = false
                if childlink.links != blank
                  assign has_sub_dropdown = true
                endif
              -%}

              <li class="{% if has_sub_dropdown %} site-nav__deep-dropdown-trigger{% endif %}">
                <a href="{{ childlink.url }}" class="site-nav__dropdown-link site-nav__dropdown-link--second-level{% if has_sub_dropdown %} site-nav__dropdown-link--has-children{% endif %}">
                  {{ childlink.title | escape }}
                  {%- if has_sub_dropdown -%}
                    <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon--wide icon-chevron-down" viewBox="0 0 28 16"><path d="m1.57 1.59 12.76 12.77L27.1 1.59" stroke-width="2" stroke="#000" fill="none"/></svg>
                  {%- endif -%}
                </a>
                {%- if has_sub_dropdown -%}
                  <ul class="site-nav__deep-dropdown">
                    {%- for grandchildlink in childlink.links -%}
                      <li>
                        <a href="{{ grandchildlink.url }}" class="site-nav__dropdown-link">{{ grandchildlink.title | escape }}</a>
                      </li>
                    {%- endfor -%}
                  </ul>
                {%- endif -%}
              </li>
            {%- endfor -%}
          </ul>
        {%- endif -%}
      {% if is_megamenu or has_dropdown %}
        </details>
      {% endif %}
    </li>

Debugging information

  • OS [Windows]
  • Version [latest]
@mzachdev mzachdev added the bug Something isn't working label Nov 10, 2023
@mzachdev mzachdev changed the title LiquidHTMLParsingError throws error when it shouldn't LiquidHTMLParsingError throws error for <details> tag Nov 10, 2023
@charlespwd
Copy link
Collaborator

charlespwd commented Nov 10, 2023

This happens because we have to strike a balance between the following two things:

  • Being helpful and telling folks they forgot to close their branches,
  • And allowing folks to be slightly dangerous with their code.

The heuristic we chose is that we only allow "two unclosed" or "two closing" HTML nodes inside Liquid branches. What we have here is an unclosed node and summary and it's very hard for us to tell that it actually closes much later down the file. It's also unclear how we're supposed to indent the code in this situation.

You could fix this by adding an endif and re-adding the if statement between the unclosed node and the child node.

{% # works because there's only one unclosed node here %}
{% if is_megamenu or has_dropdown %}
  <details
    data-hover="{{ hover_menu }}"
    id="site-nav-item--{{ forloop.index }}"
    class="site-nav__details"
  >
{% endif %}
{% if is_megamenu or has_dropdown %}
  <summary
    data-link="{{ link.url }}"
    aria-expanded="false"
    aria-controls="site-nav-item--{{ forloop.index }}"
    class="site-nav__link site-nav__link--underline{% if has_dropdown %} site-nav__link--has-dropdown{% endif %}"
  >
    {{ link.title }}
    <svg
      aria-hidden="true"
      focusable="false"
      role="presentation"
      class="icon icon--wide icon-chevron-down"
      viewBox="0 0 28 16"
    >
      <path d="m1.57 1.59 12.76 12.77L27.1 1.59" stroke-width="2" stroke="#000" fill="none"/>
    </svg>
  </summary>
{% else %}
  <a
    href="{{ link.url }}"
    class="site-nav__link site-nav__link--underline{% if has_dropdown %} site-nav__link--has-dropdown{% endif %}"
  >
    {{ link.title }}
  </a>
{% endif %}

@charlespwd
Copy link
Collaborator

👋 this came up too often. I think I have a fix for it in Shopify/theme-tools#253. Should be in soon :)

charlespwd added a commit to Shopify/theme-tools that referenced this issue Jan 9, 2024
* Small refactor of ASTBuilder for clearer push method

* Move prettier integration tests to src for better vitest integration

* VS Code settings changes

* Add full support for unclosed HTML elements inside branching code

Fixes #196
Fixes Shopify/prettier-plugin-liquid#213

* Allow 'HtmlDanglingMarkerClose' nodes to have non-dangling marker siblings

We relax the heuristic to be less annoying.

* Fixup extraneous spaces

* Clean up unused option in ASTBuilder

* Remove ieConditionalComment stuff
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants