Shopify Dawn theme source code explaination - frontend

I am currently trying to learn how to create my own custom theme from scratch and right now having trouble understanding the code of DAWN theme(wordpress free source theme).
/Sections/page.liquid
<div class="rte">
{%- if section.settings.page.content != blank -%}
{{ section.settings.page.content }}
{%- else -%}
<div class='page-placeholder-wrapper placeholder'>
{{ 'page' | placeholder_svg_tag: 'page-placeholder' }}
</div>
{%- endif -%}
</div>
{% schema %}
{
"name": "t:sections.page.name",
"tag": "section",
"class": "spaced-section",
"settings": [
{
"type": "page",
"id": "page",
"label": "t:sections.page.settings.page.label"
}
],
"presets": [
{
"name": "t:sections.page.presets.name"
}
]
}
{% endschema %}
I don't really understand what is "t:sections.page.name" why pick such a complex name? Does it retrieve any data from any files?
where is this page.liquid being used for? It looks like a bridge that connects the theme and all other sections.
My current goal is to figure out how to include all the custom section within a page template. Say if I have 10 sections writen and intended to include within a single template file. Then, I have to repeat the line {% section 'section-name' %} 10 times. And if there is more template file, the situation will just gotten worse. Is there a way to loop through all sections? Or any tutorials that I can refer to would be really helpful!
Thank you reading and answering!

Here is some explanation based on my knowledge,
For example, When you go to Online store -> Pages -> create a page via green button situated in the top right corner As per the screenshot - click steps where you noticed that the Theme template is Default page check the screenshot. That Default page is equal to your page.json template and inside the page.json [section/main-page.liquid] section is using.
Now here we have section/page.liquid which is basically for if we want page content inside a different page (page inside page)
Here is the screenshot of the page where we can notice that page.liquid is rendering click me
Learning Note : You can add this line <h2> Current template={{template}}.liquid </h2> into theme .liquid to check which template is rendering
For all sections inside the template, I guess you don't need a loop or {% section 'section-name' %} or anything as the Dawn theme is in Shopify 2.0 where all the templates are in JSON format and sections are everywhere so you can add as many as sections you want inside the template-name.JSON
Thank you

Related

Render a link field inside a paragraph template drupal 8

I have a paragraph called link. In this paragraph there is a single link field that allows multiple values. In the paragraph-link.html.twig file I want to render all of the links added to the paragraph. Instead I get the same link duplicated as many times as the number of link values. So if I add two links, it renders the first link twice. I also need it to work with external and internal links. Currently it only renders the external links properly (but only ever renders the first one).
{% for item in paragraph.field_link %}
{{ paragraph.field_link.title }}
{% endfor %}
Thanks for the comments, the following is working for external links but not internal ones. Internal link URI renders as "internal:/"
{% for item in paragraph.field_link %}
{{ item.title }}
{% endfor %}
With the help of the comments I was able to get this working as I wanted within the paragraph template. Below is the working code for a Link field that allows multiple values within a paragraph field.
{% for item in paragraph.field_link %}
{{ item.title }}
{% endfor %}

Grav CMS: how to show/hide parts of the page depending on conditions?

The Grav's documentation clearly describes how a whole page or a folder could be hidden from unregistered users. It also describes how a whole page could be seen only by particular user groups.
But what about pieces of a page, let's say, some links or a private info I want to show on some conditions?
Ok, for registered users I found a snippet at Login plugin docs:
{% if grav.user.authenticated %}
content for registered users goes here
{% endif %}
But going wider - how can I show/hide pieces of a particular page depending on some custom logic in PHP code, i.e. not necessarily user related?
I'm thinking about a twig/shortcode plugin, something like:
{% if some.custom.condition.or.PHP.function %}
hidden content goes here
{% endif %}
or
[hidden_if_something] hidden content goes here [/hidden_if_something]
But not sure how exactly this should be implemented. So working examples would be appreciated. Thanks.
There is a recipe in the Grav documentation here. This provides an example of how to render the output of a PHP code result in a twig template.
In the example they create a plugin, and implement a twig extension providing access to a php function. They can then simply call that php function like in a twig template.
{{ example() }}
Following that example, you can implement whatever logic you would like in php, and call the function in a twig if statement.
{% if example() == true %}
your conditional output
{% endif %

How to push values to array in templates and partials to output them in layout?

We are using Twig as our templating engine but I'm stuck with a problem of the rendering order now. See - https://straightupcraft.com/articles/twig-processing-order
We are using amp for our new site and with amp and web components in general it is necessary to import the components (once) to use them. So the idea was to create a Twig Extension to accomplish exactly this. Everytime a component is used it is called via this twig function call. The function is checking the component, adding it to a stack and you can use it from now on. The stack then is transformed into a list of imports for the head of the page.
The problem here is Twigs top to bottom rendering. When I call said function in a partial or a template the rendering of "layout.twig" already took place and all function calls below/after are not affecting the stack.
Is there an option to change the rendering to inside out, so that the rendering is first using the lowest partial and "bubbles" up to templates and finally layout without them rendering before?
Another way to get the values in layout would nice as well.
Desired behavior:
Layout.twig
{{ getAllComponents() }}
{# should output component1 and component2 #}
{% block content %}
Page.twig
{% extends Layout.twig %}
{{ addComponent('component1') }}
{% include partials.twig %}
<component1>...</component1>
partials.twig
{{ addComponent('component2') }}
<component2>...</component2>
Actual behavior:
Layout.twig
{{ getAllComponents() }}
{# is empty #}
There is no option to change this behavior. However you can use a trick to archive this:
Render your content to a variable before you call getAllComponents()
layout.twig
{% set mainContent %}
{% block content %}{% endblock %}
{% endset %}
{{ getAllComponents() }}
{{ mainContent }}
There actually is a magical solution to this problem -- some genius wrote this Deferred Twig Extension which lets you run some code (output a variable, call a function, etc) in a block near the top of your layout, but wait until the rest of the twig templates have parsed before executing them. There's an example on that github page showing how you can achieve this.
As far as I know, no you cannot switch the rendering of a TWIG template.
However, I would recommend possibly looking at the {% embed %} or {{ render }} tags.
Embed allows specific TWIG files to be placed within others with variables, so you could pass each component into their relevant partials.twig file.
Render allows the use of embedding a separate controller action, so you create a ControllerAction that took in a component variable and renders its own TWIG file.
Documentation on Embed: https://twig.sensiolabs.org/doc/2.x/tags/embed.html
Documentation containing Render: https://twig.sensiolabs.org/doc/2.x/api.html

Accessing individual fields in Drupal 8 views templates

I'm having trouble doing something that I think should be relatively simple drupal 8 views.
I have a content type called Countries. I would like to display the 3 latest country nodes on my homepage in a views block. Each country is displayed with the class "views-row" on the container div. I am using views--view--unformatted--countries--block_1.tpl to template the output.
I would like to output something like the following markup:
<a class="view-row-1" href="/link/to/node">
<img src="source-of-teaser-image.png">
<h3>Title of node</h3>
</a>
<a class="view-row-2" href="/link/to/node">
<img src="source-of-teaser-image.png">
<h3>Title of node</h3>
</a>
<a class="view-row-3" href="/link/to/node">
<img src="source-of-teaser-image.png">
<h3>Title of node</h3>
</a>
The problem I'm having is accessing individual fields in the template. If I use a view mode, I can access individual fields. If I select "show fields" in the view, I can add a field for "view result counter" and "path", which would allow me to add the "view-row-N" class and link the a tag to the node, but I can't get access to the fields individually. I have the {{row.content}} variable, but any attempt to dig further into the variable (eg row.content.field_name) gives me nothing and calling a {{dump(row.content)}} crashes the website.
I can't output this as a view mode for 2 reasons. I don't have access to the "view result counter" or "path" fields in a view mode and, even if I had these variables, some fields would be nested inside others (The image and title are nested inside the )
I feel this should really be as simple as
<a class="view-row-{{ row.content.view_result_counter }}" href="{{ row.content.path }}">
etc but I've tried everything I can think of. Am I completely on the wrong path? Twig and I are not getting along so far...
I have figured a way using kint.
Inside your views-view-unformatted.html.twig use the following code to display your individual fields:
{% for row in rows %}
{{ row.content['#view'].style_plugin.render_tokens[ loop.index0 ]['{{ YOUR_FIELD_NAME }}'] }}
{% endfor %}
Using content/view mode works in your case.
1/ In "views-view-unformatted.html.twig" you can use "loop.index" in the "for" loop to get index of the current row and add it to the "row_classes" variable.
2/In the twig template for the node you can use something like :
<a href="{{ path('entity.node.canonical', {'node': node.id}) }}">
{{ content.field_img }}
{{ node.getTitle()}}
</a>
3/You will probably get extra html but you can get rid of most of it by overriding relevant templates.
I am not sure if it's what you expect, but you can override field template:
Enable Twig debugging: https://www.drupal.org/node/1903374
Inspect your page in browser (if site is in debug mode there are comments in html with paths to templates for each element).
For example this is field template: core/themes/stable/templates/views/views-view-fields.html.twig
Copy required template into your theme folder
Add or modify markup.
You can debug template using {{ dump(variable) }} or {{ kint(variable) }}
In your case you should be using views-view-fields--countries--block_1.html.twig instead of views-view-unformatted--countries--block_1.html. twig file.
Views fields template will iterate on all rows of result. Your views-view-fields--countries--block_1.html.twig should contain below code -
<div>
<a class="view-row" href="{{variable-to-print-path }}">
<img src="{{ image-path }}">
<h3>{{ fields.title.content</h3>
</a>
</div>
You can check the fields array by using kint function like - {{ kint(fields) }}
Check for image path and anchor path variable from output of kint function.
If you want to do this in views-view-unformatted--countries--block_1.html. twig, then you can access the field values like below -
{% for row in rows %}
{% set photo = file_url(row['content']['#row']._entity.field_page_photo.entity.fileuri) %}
<li><img src={{ photo }} class="img-responsive img-circle"></li>
{% endfor %}
The solution is simple use the views fields template.
I created a new template under themes/templates folder:
views-view-fields--VIEW-NAME.html.twig
And now you can access your fields values like this:
{{ fields.field_NAME.content }}
If you want to access Individual fields in Views Twig Template along with Row Information,
Override Views Fields Template in your custom theme :
views-view-fields--VIEW-NAME.html.twig
To get the row index in the same file, Use :
{{ row.index }}

symfony3 override fields theme from vich bundle

I have installed VichUploaderBundle into my Symfony app and would like to have better control of the appearance of the upload buttons. I have taken the contents of fields.html.twig located in the bundle itself, and copied them into the same file at the path app/Resources/views/myControllerName/fields.html.twig This is also where all the other twig templates are for that set of controllers.
I can not seem to affect anything on the page through this method. Yes I have cleared the cache, I have even removed the cache directory.
Am I placing the file in the wrong place?
You can override that form theme in many ways, just when you customize vich_file_widget and/or vich_image_widget e.g.:
{% extends 'base.html.twig' %}
{% form_theme form _self %}
{% block vich_file_widget %}
{# some content… #}
{% endblock %}
{% block content %}
{{ form(my_form) }}
{% endblock %}
Thanks for the effort #jkucharovic, I was already using the 3rd method you were suggesting. My question was whether or not I put the fields.html.twig file in the correct place. Turns out I did not. For others that come along with this question, to override the fields file in the VichUploaderBundle for twig you must put a copy of the fields.html.twig file at the following path so that Symfony can override what comes with the bundle.
the fields file is found here and should not be edited...
vendor/vich/uploader-bundle/Resources/views/Form/fields.html.twig
a copy of that file should be placed here in Symfony 3. This file is editable.
app/Resources/VichUploaderBundle/views/Form/fields.html.twig

Resources