twigphp / twigphp/Twig

Add support for the ?= operator

Open
#3,697 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Investigate before 4.x Operator
Dominant language
PHP
Stars
8.4k
Forks
1.3k
Avg merge
1d 13h
Merged PRs (30d)
37

Description

I have a lot of templates that are intended to be used with {% include ... with { } %} or {% embed ... with { } %}. Conceptually, I like this a lot. It feels a lot like components in frontend frameworks or function calls.

But there are two things that bother me with how this currently works:

  1. It's quite difficult to find out which variables are expected by a template. Currently I'd need to look through the entire template to find, which variables are required, which are optional, and which aren't used at all.

  2. It's a little too complex to set a default value for an argument. Since the default filter isn't suited for this use-case I need to set default values like this:

{% set someParam = someParam is defined ? someParam : 'default value' %}

I had the idea to write my own param filter or function but that doesn't work either because the template crashes if a not defined variable is used with a custom function or filter (I guess this is caused by the strict_variables option, right?). I looked into how default deals with this. But its implementation looks quite advanced.

I think both points mentioned above could be solved at one go. But there are a lot of ways to tackle this. First of all: Is there any interest in solving these issues? I think they are tightly coupled to how both include and embed work, so I think this could help a lot of people.

One idea I have is the following:

{% params num = 1, str = 'hello', flag = false %}

In this case num should default to 1 only if it's missing from (or basically if it's not defined):

{% include ... with { ...no num here... } %}

My params* tag would basically be a shortcut for multiple set tags like the one above. This means it not only works in included or embedded templates but basically everywhere.

Now for point one (i.e. for documentation purposes) I'd also like the following to be valid:

{% params foo %}

On one hand this sends a signal to the user that there's a (potentially non-optional) variable foo required to render this template. But this tag like shown above would actually be a noop. Unless this defaults a not defined variable to null.

*) Maybe {% define ... %} is an even better name since it might work everywhere and it could set undefined variables to null.

After reading through other issues I think you wouldn't want to implement the possibility to mark a variable as required and throw if it's not defined, right? Otherwise, this is also something that could be covered by this tag.

Here's a more advanced and simplified real-live example (using define instead of params):

{# menu-item.html #}

{% define label = '', icon, link, variant = 'default' %}

{% set labelHtml %}
  <div class="variant-{{ variant }}">
    {% if icon is not null %}
      <img src="{{ icon }}">
    {% endif %}
    <span>{{ label }}</span>
  </div>
{% endset %}

{% if link is not null %}
  <a href="{{ link }}">
    {{ labelHtml }}
  </a>
{% else %}
  {{ labelHtml }}
{% endif %}

The define tag above would be equivalent to:

{% set label = label is defined ? label : '' %}
{% set icon = icon is defined ? icon : null %}
{% set link = link is defined ? link : null %}
{% set variant = variant is defined ? variant : 'default' %}

But more realistically icon and link would be missing and the template would check {% if icon is defined %}. Imo that's bad because of point 1 above. And it's not as easy to read what the actual default values are.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the existing include and embed behavior, the default filter, and how strict_variables handles undefined variables. Compare the proposed params and define syntax, including defaults and required variables, and determine a concrete scope and expected behavior before implementation.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
web-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.