Shopify / liquid

Liquid markup language. Safe, customer facing template language for flexible web apps.
https://shopify.github.io/liquid/
MIT License
11.05k stars 1.38k forks source link

How to remove Tab space with strip or strip_newlines? #1771

Closed ttnbtfy closed 8 months ago

ttnbtfy commented 9 months ago

Hi, I have the code below

// Tab length = 4

{%- capture placeholder -%}
    <div class="placeholder-head">
        <span class="placeholder"></span>
        <span class="placeholder"></span>
    </div>
    <div class="placeholder-content">
        <div class="placeholder-card">
            <span class="placeholder-media placeholder"></span>
            <span class="placeholder-title placeholder"></span>
            <span class="placeholder-meta placeholder"></span>
        </div>
        <div class="placeholder-card">
            <span class="placeholder-media placeholder"></span>
            <span class="placeholder-title placeholder"></span>
            <span class="placeholder-meta placeholder"></span>
        </div>
        <div class="placeholder-card">
            <span class="placeholder-media placeholder"></span>
            <span class="placeholder-title placeholder"></span>
            <span class="placeholder-meta placeholder"></span>
        </div>
        <div class="placeholder-card">
            <span class="placeholder-media placeholder"></span>
            <span class="placeholder-title placeholder"></span>
            <span class="placeholder-meta placeholder"></span>
        </div>
    </div>
{%- endcapture -%}

{{- placeholder | strip | strip_newlines -}}

Below is the output for the code above.

// Tab length = 4

<div class="placeholder-head">      <span class="placeholder"></span>       <span class="placeholder"></span>   </div>  <div class="placeholder-content">       <div class="placeholder-card">          <span class="placeholder-media placeholder"></span>         <span class="placeholder-title placeholder"></span>         <span class="placeholder-meta placeholder"></span>      </div>      <div class="placeholder-card">          <span class="placeholder-media placeholder"></span>         <span class="placeholder-title placeholder"></span>         <span class="placeholder-meta placeholder"></span>      </div>      <div class="placeholder-card">          <span class="placeholder-media placeholder"></span>         <span class="placeholder-title placeholder"></span>         <span class="placeholder-meta placeholder"></span>      </div>      <div class="placeholder-card">          <span class="placeholder-media placeholder"></span>         <span class="placeholder-title placeholder"></span>         <span class="placeholder-meta placeholder"></span>      </div>  </div>

I want to remove the spaces generated by the Tab button, can I do that, and if so, how? Expected output received:

<div class="placeholder-head"><span class="placeholder"></span><span class="placeholder"></span></div><div class="placeholder-content"><div class="placeholder-card"><span class="placeholder-media placeholder"></span><span class="placeholder-title placeholder"></span><span class="placeholder-meta placeholder"></span></div><div class="placeholder-card"><span class="placeholder-media placeholder"></span><span class="placeholder-title placeholder"></span><span class="placeholder-meta placeholder"></span></div><div class="placeholder-card"><span class="placeholder-media placeholder"></span><span class="placeholder-title placeholder"></span><span class="placeholder-meta placeholder"></span></div><div class="placeholder-card"><span class="placeholder-media placeholder"></span><span class="placeholder-title placeholder"></span><span class="placeholder-meta placeholder"></span></div></div>
Xeffen25 commented 8 months ago

There are 2 (or more) solutions to this problem.

  1. Is to use the filter "remove" and remove the tabs, usualy would work with '\t', rihgt? Well... not in liquid so you create a variable with the tab character. The way I found how to achieve this is by decoding base64 which would be "CQ==". so the solution would look like this:
    {%- capture placeholder -%}
    <div class="placeholder-head">
        <span class="placeholder">a</span>
        <span class="placeholder"></span>
    </div>
    <div class="placeholder-content">
        <div class="placeholder-card">
            <span class="placeholder-media placeholder"></span>
            <span class="placeholder-title placeholder"></span>
            <span class="placeholder-meta placeholder"></span>
        </div>
        <div class="placeholder-card">
            <span class="placeholder-media placeholder"></span>
            <span class="placeholder-title placeholder"></span>
            <span class="placeholder-meta placeholder"></span>
        </div>
        <div class="placeholder-card">
            <span class="placeholder-media placeholder"></span>
            <span class="placeholder-title placeholder"></span>
            <span class="placeholder-meta placeholder"></span>
        </div>
        <div class="placeholder-card">
            <span class="placeholder-media placeholder"></span>
            <span class="placeholder-title placeholder"></span>
            <span class="placeholder-meta placeholder"></span>
        </div>
    </div>
    {%- endcapture -%}
    {%- assign tabchar = "CQ==" | base64_decode -%}
    {{- placeholder | strip_newlines | remove: tabchar -}}
  2. If you for some reason have tab elements inside your code you would need to split the string, iterate through it with a for, have a boolean variable to detect if your inside an html element, meaning when you pass through a '<' or '>' you would have to change its value to true or false and if your not inside an element remove all the characters directly. If you for some reason have '<' or '>' elements inside you would have to complecate the matter even further.
    {%- capture placeholder -%}
    <div class="placeholder-head">
        <span class="placeholder">a</span>
        <span class="placeholder"></span>
    </div>
    <div class="placeholder-content">
        <div class="placeholder-card">
            <span class="placeholder-media placeholder"></span>
            <span class="placeholder-title placeholder"></span>
            <span class="placeholder-meta placeholder"></span>
        </div>
        <div class="placeholder-card">
            <span class="placeholder-media placeholder"></span>
            <span class="placeholder-title placeholder"></span>
            <span class="placeholder-meta placeholder"></span>
        </div>
        <div class="placeholder-card">
            <span class="placeholder-media placeholder"></span>
            <span class="placeholder-title placeholder"></span>
            <span class="placeholder-meta placeholder"></span>
        </div>
        <div class="placeholder-card">
            <span class="placeholder-media placeholder"></span>
            <span class="placeholder-title placeholder"></span>
            <span class="placeholder-meta placeholder"></span>
        </div>
    </div>
    {%- endcapture -%}
    {%- assign tabchar = "Cg==" | base64_decode -%}
    {%- assign linechar = "CQ==" | base64_decode -%}
    {%- assign result = "" -%}
    {%- assign placeholder = placeholder | split: "" -%}
    {%- assign isHTML = false -%}
    {%- for char in placeholder -%}
    {%- if isHTML == false -%}
        {%- if char != tabchar and char != linechar -%}
            {%- assign result = result | append: char -%}
            {%- if char == '<' -%}
                {%- assign isHTML = true -%}
            {%- endif -%}
        {%- endif -%}
    {%- else -%}
        {%- assign result = result | append: char -%}
        {%- if char == '>' -%}
            {%- assign isHTML = false -%}
        {%- endif -%}
    {%- endif -%}
    {%- endfor -%}
    {{- result -}}

    In this second example line char Removes line breaks between elements instead of using a filter for strip_newlines, by using the filter you would iterate through the strig twice and there is no need for that. Also in this method I implemented it keeps the information inside the elements thats why in both examples I added a random 'a' to test. Last thing is that in your code yoir adding a "split" filter. At least when I tested it, it made no difference with it being there so I would remove it.

Xeffen25 commented 8 months ago

@ttnbtfy

ttnbtfy commented 8 months ago

Hi @Xeffen25 I tried solution 1 and it worked like a charm. Thank you!