Volt template check type of object - phalcon

VOLT template gives the possibility, to check the type of an object:
{% set external = false %}
{% if external is type('boolean') %}
{{ "external is false or true" }}
{% endif %}
Is there a possibility, to check if the object is type of a model like this:
{% if user is type('user') %}
{{ "user is type of user" }}
{% endif %}
Thanks for your help

As of today (2021), there still seems to be no solution in Phalcon. To solve this for me, I've added a custom Volt function:
$compiler = $this->volt->getCompiler();
$compiler->addFunction('instanceof', function ($resolvedArgs, $exprArgs) {
$object = $instance = 'null';
if (isset($exprArgs[0])) {
$object = $exprArgs[0]['expr']['value'] ?? 'null';
}
if (isset($exprArgs[1])) {
$instance = $exprArgs[1]['expr']['value'] ?? 'null';
}
return '$' . $object . ' instanceof ' . $instance;
});
In Volt, I'm able to check instance of object now with:
{% if instanceof(myobject, \DateTime) %}
{% endif %}

You must create a functiton in services.php here

Related

DBT - how can i add model configuration (using a macro on {{this}}) in dbt_project.yml

I want to add node_color to all of my dbt models based on my filename prefix to make it easier to navigate through my dbt documentation :
fact_ => red
base__ => black.
To do so i have a macro that works well :
{% macro get_model_color(model) %}
{% set default_color = 'blue' %}
{% set ns = namespace(model_color=default_color) %}
{% set dict_patterns = {"base__[a-z0-9_]+" : "black", "ref_[a-z0-9_]+" : "yellow", "fact_[a-z0-9_]+" : "red"} %}
{% set re = modules.re %}
{% for pattern, color in dict_patterns.items() %}
{% set is_match = re.match(pattern, model.identifier, re.IGNORECASE) %}
{% if is_match %}
{% set ns.model_color = color %}
{% endif %}
{% endfor %}
{{ return({'node_color': ns.model_color}) }}
{% endmacro %}
And i call it in my model .sql :
{{config(
materialized = 'table',
tags=['daily'],
docs=get_model_color(this),
)}}
This works well but force me to add this line of code in all my models (and in all the new ones).
Is there a way i can define it in my dbt_project.yml to make it available to all my models automatically?
I have tried many things like the config jinja function or this kind of code in dbt_project.yml
+docs:
node_color: "{{ get_model_color(this) }}"
returning Could not render {{ get_model_color(this) }}: 'get_model_color' is undefined
But nothing seems to work
Any idea? Thanks

Replace Filter - How to pass a variable for the string to be replaced?

I am currently working on a symfony 6 project and try to pass a variable into a replace filter from Twig. However that does not work for me.
I tried it like this:
{% if form.vars.data.fileName|default %}
{% set system_type_short = get_env("SYSTEM_TYPE_SHORT") %}
{% set replaces = '/var/www/' ~ system_type_short ~ '.domain.de/public/uploads/images/' %}
{% set url = 'uploads/images/' ~ form.vars.data.fileName|replace({(replaces): ('')}) %}
<img src="{{ asset(url) }}" height="100"><br><br>
{% endif %}
The error I get:
A hash key must be followed by a colon (:). Unexpected token "punctuation" of value "{" ("punctuation" expected with value ":").
Can anyone tell me what I am doing wrong or how to pass a variable into the filter function "replace"?
You cannot use the variable syntax ({{ }}) when already in a twig expression.
So you just have to fix {{system_type_short}} and use string concatenation ~ instead.
You would get:
{% if form.vars.data.fileName|default %}
{% set system_type_short = get_env("SYSTEM_TYPE_SHORT") %}
{% set url = 'uploads/images/' ~ form.vars.data.fileName|replace({('/var/www/' ~ system_type_short ~ '.domain.de/public/uploads/images/'): ''}) %}
<img src="{{ asset(url) }}" height="100"><br><br>
{% endif %}

Shopify - best way to incrementally build up a string in Liquid

I have an array of cities. I want to create a formatted string that can be output to the page... something like New York, Miami and Denver.
In JavaScript, I'd do something like this (rough):
const cities = ['nEW-york','MIAMI FL', 'denver'];
let out = '';
cities.forEach((city, i) => {
if(i === cities.length-1 && i !== 0) {
out += ` and ${formatCity(city)}.`;
} else {
if(i !== 0) {
out += ', ';
}
out += city;
}
});
console.log(out);
You can assume my formatCity() function knows what different kinds of input to expect and how to transform it into a nicely formatted city name (ex nEW-york --> New York).
The first way I thought to do this in Liquid was to use a for loop and capture, which just creates a mess of whitespace and newlines and whatnot.
Instead, I went with an approach similar to how i' do it in JavaScript, using the append filter.
{% assign cities = 'nEW-york,MIAMI FL,denver' | split: ',' %}
{% assign out = '' %}
{% for city in cities %}
{% if forloop.last and forloop.first == false %}
{% assign out = out | append: ' and ' | append: city | append: '.' %}
{% elsif forloop.first == false %}
{% assign out = out | append: ', ' | append: city %}
{% else %}
{% assign out = out | append: city %}
{% endif %}
{% endfor %}
{%- capture prettyCityStr -%}
{%- render 'format-cities', str: out -%}
{% endcapture %}
{{- prettyCityStr -}}
And you can assume that my format-cities snippet does the same as the formatCity() function above. You should also assume that it's not just as simple as throwing the word and in before the last city.
I have no idea if this method (used extensively on any given page... with WAY larger arrays of cities) would cause any performance issues (it seems to me that re-initializing the out variable over and over again may be problematic) or if there's just a more standard way.
I don't work in Liquid often - any input from anyone who does would be greatly appreciated.

How to create and update a global variable in Jinja?

I'd like to create a global (boolean) variable with Jinja and update it in an if-statement. I try to do this as follows:
{% set variable = true %}
{% if True %}
{% set variable = false %}
{% endif %}
{{ variable }}
I'd like the print to be False, but now it is True.
Should I create a variable to a namespace or is there simpler way? Thanks for your help!

How to use variables in Twig filter 'replace'

Handing over an array from php of form
$repl_arr = array('serach-string1' => 'replace1', ...)
to a Twig template I would like to replace strings in a Twig variable per replace filter similar to this:
{{ block | replace({ repl_arr }) }}
That does not function and neither a variable loop like
{% for key,item in repla_arr %}
{% set var = block | replace({ key : item }) %}
{% endfor %}
does. What is wrong with it? How could it work?
Either you pass the whole array, or you loop the replaces.
But when looping the replaces you need to wrap key and value in parentheses to force interpolation of those
{% set replaces = {
'{site}' : '{stackoverflow}',
'{date}' : "NOW"|date('d-m-Y'),
} %}
{% set haystack = '{site} foobar {site} {date} bar' %}
{{ haystack | replace(replaces) }}
{% set output = haystack %}
{% for key, value in replaces %}
{% set output = output|replace({(key) : (value),}) %}
{% endfor %}
{{ output }}
fiddle