A way access field content with liquid - orchardcms

I am using the latest NuGet version of orchard core. As I want to use Bulma as CSS Framework, I Need to create tepmlates. One of several Problems that I have is: How can I Access the field contents from within a liquid template.
For instance the Blog theme has the content type Article. Within Article there is a field Subtitle. I created the template Article-TextField as
<h2 class="subtitle">{{ Model.Field.Text }}</h2>
The similar .cshtml template works, but apparently with a liquid template, there is no way to Access the TextField Text property. How can I do it the right way?

The problem is that the OrchardCore.ContentFields module doesn't register the TextField type with the Liquid's TemplateContext.GlobalMemberAccessStrategy service, which prevents you from accessing any members on the TextField object.
The module does register DisplayTextFieldViewModel like so:
TemplateContext.GlobalMemberAccessStrategy.Register<DisplayTextFieldViewModel>();
Not only is this unnecessary because the LiquidViewTemplate already registers the model automatically, it also doesn't help you much, since you can only access the model's Field property, but not its Text property.
For example, this will yield some output:
{{ Model }}
This will too:
{{ Model.Field }}
But as you correctly noticed, this won't:
{{ Model.Field.Text }}
This is clearly an omission in Orchard Core, specifically in the ContentFields module.
Since you're using the NuGet packages, you can't hack it into the source code obviously. But what you could do is add a Startup class to your theme that derives from StartupBase and add the following static constructor:
static Startup()
{
TemplateContext.GlobalMemberAccessStrategy.Register<TextField>();
}
Make sure to reference the OrchardCore.ContentFields NuGet package and import the OrchardCore.ContentFields.Fields namespace for your theme to compile.
After that, you will be able to access the Text property from your Liquid template.
Finally, I would recommend that you file an issue on GitHub about this omission so that you can ultimately remove the code I mentioned from your theme's Startup file.

Related

I cannot modify twig file

Has anyone else encountered this problem?
I cannot modify files of this type:
{% include 'mobshop/template/common/icons/wishlist.twig' %}
The file "wishlist.twig" is modified in the log but the changes do not appear live.
Do you have any suggestions?
Short answer: you can't modify with OCMod twig files that are added via include method inside the twig template.
How twig include works?
include is twig method that allows you to add partials into your theme which is a cool feature. when twig engin runs, it compiles the template by following the link and adding the html part into the final html output string.
How OCMod works?
OCmod is basically a function that takes in the path of the file (in our case the twig template file path) and after parsing the string modifies it and saves to the OCMod cache.
Then, when OpenCart asks for that file, the OCMod engine tries to first return the cached file, and if that is not available, then the original file.
so all files that are wrapped in modification('') method have this support.
The reason why twig include is not supported by OCMod
From the logic above we can see that the OCMod modification method simply never sees the twig partial file path from the Include method. It is jsut beyond its scope.
The modification method sees only a string {% include 'path-to-partial-file' %} and that is it. it never dives into that path and never tries to create a OCMod cache off of that file.
Conclusion.
You should not use "include" in your themes at all. Its just bad practice in OpenCart themes. Although personally I love this feature of Twig, I am also forced to avoid it.
The only way you should add partials in OpenCart is via the Controller ($this->load->controller('...')) attaching it to the $data field and then displaying it in the template.
And if you still MUST have this feature
PHP Twig engine is a powerful tool and you can extend it to your needs. You can still add an extension that can make the include method to work with OCmod, although I have never added that feature.
Here is a twig extension https://github.com/Dreamvention/2_d_twig_manager/blob/master/system/library/template/Twig/Extension/DTwigManager.php that you can use as an example and modify to your needs.
Enjoy!

Druplal view in twig is not rendered

new to drupal.
I have created a view called "my_view_2".
Inside my twig templates I use {{ my_view_2}} to render that view but nothing appears on the page.
If I declare the display of the view as page and assign a node to the view, then the view is rendered. But this way the node template is lost.
The above happens only to some views not very view I have and I can not find the differences between those that working and those that does not working.
any help is appreciated.
Looks like you want to create a view with some kind of display then use twig template to style it. If that's the case, then decide which twig template you want override and copy it over to your /theme folder.
Locate the template you wish to override.
Copy the template file from its base location into your theme folder.
(optionally) Rename the template according to the naming conventions in order to target a more specific subset of areas where the template is used.
Modify the template as you want.
With respect to views look at the below location for which template to copy/override :
core/themes/stable/templates/views/views-view.html.twig).
For example, if we want to override "views-view.html.twig" template for our view, the following template names are valid:
views-view--[viewid]--[view-display-id].html.twig
views-view--[viewid]--page.html.twig
views-view--block.html.twig
views-view--[viewid].html.twig
views-view.html.twig
Once you copy a template file into your theme and clear the cache, Drupal will start using your instance of the template file instead of the base version.
Reference:
Documentation:
https://www.drupal.org/docs/8/theming/twig/twig-template-naming-conventions
https://www.drupal.org/docs/8/theming/twig/working-with-twig-templates

Page template - Object reference not set to an instance of an object

I have a page template that has this line of code below:
<div id="<%= CurrentDocument.NodeAlias %>" class="lvl3">
Things work - the id value shows correctly. However, when using the Page Templates module Design tab, there's an error. In Event log, I saw the error message "Object reference not set to an instance of an object". Taking the id snippet out, the error is gone. I'm not sure what the error means and how to fix it. Could you help?
I do need some page-specific unique identifier in there (NodeAlias in this case) for other purposes.
The answer is pretty simple - if you open your page template in Kentico Page Templates application - your CurrentDocument is always null (because you are editing Template itself without specific document).
You could do absolutely the same thing in Pages application with the Design tab. It's also possible to edit all the template properties from there, including the Layout:
Using code blocks on page template layout is not supported. I assume you are using ASCX layout. Moreover your code looks more like a macro - so, maybe you are using HTML layout type? If yes, then the syntax should be {%CurrentDocument.NodeAlias%}
If you are using ASCX layout you may face also this issue: https://devnet.kentico.com/articles/the-controls-collection-cannot-be-modified-because-the-control-contains-code-blocks
Note that in portal engine the life cycle is bit modified, so we cannot ensure the code blocks will work every time - it may work sometimes. It mainly depends on what other web parts/controls and in what order are placed in the page template. I would rather recommend using the workaround from the article.
Or, you can give it a try, with no guarantee, this may work in certain cases, you need to specify the full namespace:
<%= CMS.MacroEngine.MacroResolver.Resolve("{%CurrentDocument.NodeAlias#%}") %>

Bolt-CMS Using extensions in page?

I read this from a recent answer to a question:
After enabling the extension, just use {{ twitterfeed() }} in your templates.
But, what if I only want say a contact form on one page? Putting the tag in the page's text field doesn't work. And putting it in the template would have it available on all the pages using that template. Do I have to duplicate a template to use only for the contact page? If not where do I put the contact form tag?
I went to Bolt's extension page, selected "how to use extensions" from the menu, and got this message:
No proper name for a page in the docs. Bye!
Perhaps someone at Bolt could fix the URL?
I would like to know why none of the extensions I want to use are not working. I am clearly missing a vital piece of info.
Thank you.
After enabling the extension, just use {{ twitterfeed() }} in your templates.
The Twig function {{ twitterfeed() }} belongs (generally speaking) in a Twig template file. You can use Twig in record fields, but that requires setting allowtwig: true for that Contenttype field.
But, what if I only want say a contact form on one page?
There are a few ways to do this, but the easiest way is to make a copy of your sites template file for the page's Contenttype and select that template for the 'Contact' record. The default 'pages' Contenttype that comes with Bolt has a templateselect field type that enables this.
No proper name for a page in the docs. Bye!
Fixed! Thanks for pointing it out.

EE alternative to WordPress shortcodes?

Any way in Expression Engine to simulate Wordpress' shortcode functionality?
I want to abide by community rules, and there's a disclaimer when clicking in the "answer" section of an existing question that says I should actually ANSWER the question, not respond to other answers.
As such, I have the same question as the one above. I am a dev with roots in WordPress and I would like to mimic the behavior of WP shortcodes in Expression Engine. All I want to do is save a snippet of code as a template that can be re-used all across my site.
For example, if I want to use an accordion menu on several pages, I could just click click while editing a page and the code appears with placeholder content that the user/dev can then replace with real content). Do I need a graphic slideshow? Click click, define the images/headings/text overlays.
As I'm posting this, I'm about to scour the EE plug-ins library but since I haven't found anything before, I wanted to post here first.
I cover an approach that I've used before in http://www.tyssendesign.com.au/articles/cms/more-stash-examples/ along with a couple of other examples of using Stash.
Short answer: there is not such a thing ... yet. The Shortcode add-on is currently in beta.
Long answer for now: use custom fields. Example: a Matrix field for your accordion, with your columns defined, and add as many row as you like. Then add tags for that in your template.
Same with a Gallery - create a Gallery field (Matrix works great for this again), then add the code to your template to build the gallery.
If these fields are made optional, then they only appear on the front-end when used.
If you want to get fancy and inject these chunks of content into your main content area, you can use NSM Transplant to do so.
Here's a simplified snippet of code I use on one site to acheive this:
{exp:nsm_transplant:body}
{inline_media}
{exp:nsm_transplant:content id="media_{row_count}"}
<figure class="{alignment}">
{exp:ifelse parse="inward"}
{if image}
{if "{alignment}" == "aligncenter"}
{exp:ce_img:make src="{image:resized}" width="860" quality="80" output='<img src="{made_url}" alt="" />'}
{if:else}
{exp:ce_img:make src="{image:resized}" width="430" quality="80" output='<img src="{made_url}" alt="" />'}
{/if}
{if:elseif video}
{if "{alignment}" == "aligncenter"}
{exp:antenna url="{video}" max_width="860"}
{if:else}
{exp:antenna url="{video}" max_width="430"}
{/if}
{if:elseif gallery}
{gallery}{embed="galleries/_embed" entry_id="{entry_id}"}{/gallery}
{/if}
{if caption}<figcaption>{caption}</figcaption>{/if}
{/exp:ifelse}
</figure>
{/exp:nsm_transplant:content}
{/inline_media}
{content}
{/exp:nsm_transplant:body}
In this case authors use {media_1}, {media_2} etc, to embed photos, videos, and galleries inside the content.
Another solution you can look at is Content Elements, which allows a more freeform method of populating an entry with a single custom field.
Hope that helps!
You can also use global variables within EE templates. You cannot use EE tags inside templates, but global variables do work. So anything that you can save as a global variable (possibly including variables made with the addon Low Variables, but I have not verified that) can be included into an EE template.
So if you need static HTML, or images, or whatever, you can absolutely mimic quite a bit of shortcode functionality by creating global vars and invoking them using the ordinary {global_var_name} syntax inside an entry field. Note that EE tags inside global variables will not get parsed, though, so you cannot use this to do an end run around parsing restrictions!

Resources