Volt not including file if path is concatenated - phalcon

I'm trying to iterate through a Model collection in volt:
{% if model.elements|length > 0 %}
{% for element in model.getElements() %}
{% include "partials/panels/edit-" ~ element.getType() ~ ".volt" %}
{% endfor %}
{% endif %}
The type can be text or images. If i use the above code, i get the error:
View '/path/to/phalcon/apps/frontend/views/partials/panels/edit-image.volt' was not found in the views directory
I'm sure that the file exists, since if i changethe include, it'll work:
{% include "partials/panels/edit-image.volt" %}
It'll also fail on:
{% include "partials/pandels/edit-" ~ "image.volt %}
What is the reason that the first version is producing that error?
( I know i could just use ifs.. But theres quite a list of element types later on. )

This will not work.
To include view dynamically use partial:
{% if model.elements|length > 0 %}
{% for element in model.getElements() %}
{{ partial( "partials/panels/edit-" ~ element.getType() ) }}
{% endfor %}
{% endif %}
There is no '.volt' since partial will add it.

Related

DBT run model only once

I've created a model to generate a calendar dimension which I only want to run when I explicitly specify to run it.
I tried to use incremental materialisation with nothing in is_incremental() block hoping dbt would do nothing if there was no query to satisfy the temporary view. Unfortunately this didn't work.
Any suggestion or thoughts for how I might achieve this greatly appreciated.
Regards,
Ashley
I've used a tag for this. Let's call this kind of thing a "static" model. In your model:
{{ config(tags=['static']) }}
and then in your production job:
dbt run --exclude tag:static
This doesn't quite achieve what you want, since you have to add the selector at the command line. But it's simple and self-documenting, which is nice.
I think you should be able to hack the incremental materialization to do this. dbt will complain about empty models, but you should be able to return a query with zero records. It'll depend on your RDBMS if this is really much better/faster/cheaper than just running the model, since dbt will still execute a query with the complex merge logic.
{{ config(materialized='incremental') }}
{% if is_incremental() %}
select * from {{ this }} limit 0
{% else %}
-- your model here, e.g.
{{ dbt_utils.date_spine( ... ) }}
{% endif %}
Your last/best option is probably to create a custom materialization that checks for an existing relation and no-ops if it finds one. You could borrow most of the code from the incremental materialization to do this. (You would add this as a macro in your project). Haven't tested this, but to give you an idea:
-- macros/static_materialization.sql
{% materialization static, default -%}
-- relations
{%- set existing_relation = load_cached_relation(this) -%}
{%- set target_relation = this.incorporate(type='table') -%}
{%- set temp_relation = make_temp_relation(target_relation)-%}
{%- set intermediate_relation = make_intermediate_relation(target_relation)-%}
{%- set backup_relation_type = 'table' if existing_relation is none else existing_relation.type -%}
{%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}
-- configs
{%- set unique_key = config.get('unique_key') -%}
{%- set full_refresh_mode = (should_full_refresh() or existing_relation.is_view) -%}
{%- set on_schema_change = incremental_validate_on_schema_change(config.get('on_schema_change'), default='ignore') -%}
-- the temp_ and backup_ relations should not already exist in the database; get_relation
-- will return None in that case. Otherwise, we get a relation that we can drop
-- later, before we try to use this name for the current operation. This has to happen before
-- BEGIN, in a separate transaction
{%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation)-%}
{%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}
-- grab current tables grants config for comparision later on
{% set grant_config = config.get('grants') %}
{{ drop_relation_if_exists(preexisting_intermediate_relation) }}
{{ drop_relation_if_exists(preexisting_backup_relation) }}
{{ run_hooks(pre_hooks, inside_transaction=False) }}
-- `BEGIN` happens here:
{{ run_hooks(pre_hooks, inside_transaction=True) }}
{% set to_drop = [] %}
{% if existing_relation is none %}
{% set build_sql = get_create_table_as_sql(False, target_relation, sql) %}
{% elif full_refresh_mode %}
{% set build_sql = get_create_table_as_sql(False, intermediate_relation, sql) %}
{% set need_swap = true %}
{% else %}
{# ----- only changed the code between these comments ----- #}
{# NO-OP. An incremental materialization would do a merge here #}
{% set build_sql = "select 1" %}
{# ----- only changed the code between these comments ----- #}
{% endif %}
{% call statement("main") %}
{{ build_sql }}
{% endcall %}
{% if need_swap %}
{% do adapter.rename_relation(target_relation, backup_relation) %}
{% do adapter.rename_relation(intermediate_relation, target_relation) %}
{% do to_drop.append(backup_relation) %}
{% endif %}
{% set should_revoke = should_revoke(existing_relation, full_refresh_mode) %}
{% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}
{% do persist_docs(target_relation, model) %}
{% if existing_relation is none or existing_relation.is_view or should_full_refresh() %}
{% do create_indexes(target_relation) %}
{% endif %}
{{ run_hooks(post_hooks, inside_transaction=True) }}
-- `COMMIT` happens here
{% do adapter.commit() %}
{% for rel in to_drop %}
{% do adapter.drop_relation(rel) %}
{% endfor %}
{{ run_hooks(post_hooks, inside_transaction=False) }}
{{ return({'relations': [target_relation]}) }}
{%- endmaterialization %}
We are working with dbt run --select MODEL_NAME for each model we want to run. So a dbt run in our environment never executes more then one model. By doing so you never run in a situation where you execute a model by accident.

On Shopify, check if a given product is not on any collection

Within the product page, I would like to hide a certain element if the current product isn't associated with any collection. Is there any way to check it with Liquid ?
The object product.collections is an array containing all collections where the product is listed.
So you may use this:
{% if product.collections.size < 1 %}
Do something
{% endif %}
Documentation about arrays here:
https://shopify.dev/api/liquid/filters#size
{% if 0 == product.collections | size %}
!! put your code here !!
{% endif %}
Or
{% for _ in product.collections %}
{% else %}
!! put your code here !!
{% endif %}

Django template syntax error: could not parse remainder % 2

I am getting a TemplateSyntaxError: "could not parse remainder % 2 from num%2":
{% if num%2 ==0 %}
{{"Even"}}
{% else %}
{{"Odd"}}
{% endif %}
You can't use arbitrary Python expressions in Django templates. You should create a custom filter for them.
However, for your expression there is a built-in tag divisibleby. From its example:
{{ value|divisibleby:"2" }}
If value is 4, the output would be True. So the final answer looks like (untested):
{% if num|divisibleby:"2" %}
Even
{% else %}
Odd
{% endif %}

can i use OR in Shopify case

let say I have three products and made a case
I want to know if I can use OR instead of duplicating the content again
{% case shipping_method.title %}
{% when 'packageA' || 'packageB' %}
around 5000 lines
{% when 'packageC' %}
{% endcase %}
Yes you can but it must be a valid syntax. || is not a valid operator in liquid.
You have to use or instead so it becomes {% when 'packageA' or 'packageB' %}

Remove variants from variants array on product in Liquid

Good evening! I am trying to remove variants from the variant array on a product using pure Liquid(Shopify templating language). I would only like to use javascript as a last resort.
Below is where I am so far. Anything that is the variant in the if check needs to be removed from currentProduct.variants.
{% assign currentProduct = product %}
{% for variant in currentProduct.variants %}
{% include 'shappify-variant-is-csp' %}
{% if csp_variant != 1 %}
//need to remove the object that meets this if statement
{% endif %}
{% endfor %}
I'm pretty sure you're going to need to use some javascript to achieve this. Take a look at this article on the Shopify wiki: How do I remove sold out variants from my options drop-downs.
Modifying the code in that article for your situation, you'll want something like this:
{% for variant in product.variants %}
{% include 'shappify-variant-is-csp' %}
{% if csp_variant != 1 %}
jQuery('.single-option-selector option').filter(function() { return jQuery(this).html() === {{ variant.title | json }}; }).remove();
{% endif %}
{% endfor %}
jQuery('.single-option-selector').trigger('change');