We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Strip whitespace

I have this snippet in a Volt template:

<div class="conditions">
    {% if Group is defined %}
        {% for Condition in Group.Conditions %}
            {{ partial('award/partials/condition',['field':Condition.field,'operator':Condition.operator,'value':Condition.value,'parent_id':Group.id,'id':Condition.id]) }}
        {% endfor %}
        {% for Group in Group.Groups %}
            {{ partial('award/partials/group',['Group':Group]) }}
        {% endfor %}
    {% endif %}
</div>

As you can see there is indentation (spaces) and newlines. These whitespace characters get included in the rendered HTML, making it impossible for me to target .conditions:empty in my CSS.

Does volt have a stripwhitespace tag? Something I could use like:

{% stripwhitespace %}
    <div class="conditions">
        {% if Group is defined %}
            {% for Condition in Group.Conditions %}
                {{ partial('award/partials/condition',['field':Condition.field,'operator':Condition.operator,'value':Condition.value,'parent_id':Group.id,'id':Condition.id]) }}
            {% endfor %}
            {% for Group in Group.Groups %}
                {{ partial('award/partials/group',['Group':Group]) }}
            {% endfor %}
        {% endif %}
    </div>
{% endstripwhitespace %}

The rendered result of which would be (assuming Group is not defined)

<div class="conditions"></div>

I know I could manually remove all the indentation and newlines, but that's hella unreadable.

I use this regex to minify html responses. It's overload Phalcon\Application::init() but the right way is a plugin

public function init()
    {
        $content = $this->handle()->getContent();

        if (strtolower(substr($content, 0, 15)) === '<!doctype html>') {
            $content = preg_replace(
                [
                    '#(?ix)(?>[^\S ]\s*|\s{2,})(?=(?:(?:[^<]++|<(?!/?(?:textarea|pre|script)\b))*+)' .
                    '(?:<(?>textarea|pre|script)\b|\z))#',
                    '#>\s+<#',
                ],
                [
                    ' ',
                    '><',
                ],
                $content
            );
        }

        return $content;
    }

Good luck

Thanks Degiovanni (or is your first name Emilio?).

I don't want to strip whitespace all the time. Most of the time I don't care - just in this particular instance.

By "plugin" do you mean "extension" as mentioned here: https://docs.phalcon.io/en/latest/volt#extending-extensionss ? Unfortunately that doesn't seem to allow for new tags, and the documentation is pretty sparse.

I'm Emilio. Degiovanni is my surname ;)

I think what you have to do is implement the event compileStatement docs I've never done it but it seems to be the right way

Good luck and then show us your result

edited Nov '18

Haven't got a lot of experience with volt, but just off the top of my head; Volt allows for php tags to be used, right? If so, perhaps you could do something along the lines of:

<?php ob_start(); ?>
    <div class="conditions">
        {% if Group is defined %}
            {% for Condition in Group.Conditions %}
                {{ partial('award/partials/condition',['field':Condition.field,'operator':Condition.operator,'value':Condition.value,'parent_id':Group.id,'id':Condition.id]) }}
            {% endfor %}
            {% for Group in Group.Groups %}
                {{ partial('award/partials/group',['Group':Group]) }}
            {% endfor %}
        {% endif %}
    </div>
<?php echo join('', array_map('trim', explode("\n", ob_get_clean()))); ?>

Not tried it, it's a bit of a hack, and it's not particularly Volt-y (ie, doesn't use Volt tags, etc.) but could something like it work for you?

I'm no longer relying on a lack of whitespace for my user interface. Nonetheless, I tested this out and it rendered the output perfectly. Thanks!

I put non-Volt php tags in my templates all the time. Sometimes it's just easier to fall back to raw PHP than to try to wrangle Volt into submission. If I were to implement this, I'd probably make declare a couple functions like stripstart() and stripend - just to make it a bit cleaner.