I have to work with an array of information extracted from a database and I want to display each part of this array according to a criterion, so it is better to make the test in the PHP or in the Twig template?
Depends on a couple of things:
the complexity of the test
The number of places you need to execute this test logic in.
If it's just something like a simple comparison like {{ product.color == 'red' ? 'love' : 'hate' }} then you should most likely put it in the twig template itself. If it is more complex it's best to put it in PHP code to keep it readable and thus separate the layout from the logic.
If you need to do this test in more than a couple of places you should also put it in a PHP object method and use that in all of those places. That way you do not have to change the 'red' color in multiple places if you'd ever want to change it.
Related
I'm creating a set of custom templates and structures for a Liferay site.
One structure provides for a repeatable section, which its matching template then iterates over.
However, for styling reasons, I need to know how many instances of the repeatable section are actually present, and I need to know before I loop.
So, the template code is something like this:
#foreach($thisChunk in $chunk.getSiblings())
[emit some HTML]
#end
I want to do some conditional logic before the foreach, and emit a different CSS classname on the containing element depending on how many $chunks there are.
Any ideas how to access the number of siblings without looping through them first?
Easy: $chunk.getSiblings().size()
How to find out? It's a plain old Java object (java.util.ArrayList in my quick test). You can find this out when you just temporarily debug your template with $chunk.getSiblings().getClass().getName() and then continue with the interface of that class.
I'm relatively new to Expression Engine, and as I'm learning it I am seeing some stuff missing that WordPress has had for a while. A big one for me is shortcodes, since I will use these to allow CMS users to place more complex content in place with their other content.
I'm not seeing any real equivalent to this in EE, apart from a forthcoming plugin that's in private beta.
As an initial test I'm attempting to fake shortcodes by using delimited strings (e.g. #foo#) in the content field, then using a regex to pull those out and pass them to a function that can retrieve the content out of EE's database.
This brings me to a second question, which is that in looking at EE's API docs, there doesn't appear to be a simple means of retrieving the channel entries programmatically (thinking of something akin to WP's built-in get_posts function).
So my questions are:
a) Can this be done?
b) If so, is my method of approaching it reasonable? Or is there something stupidly obvious I'm missing in my approach?
To reiterate, my main objective here is to have some means of allowing people managing content to drop a code in place in their content that will be replaced with channel content.
Thanks for any advice or help you can give me.
Here's a simple example of the functionality you're looking for.
1) Start by installing Low Replace.
2) Create two Global Variables called gv_hello and gv_goodbye with the values "Hello" and "Goodbye" respectively.
3) Put this text into the body of an entry:
[say_hello]
Nice to see you.
[say_goodbye]
4) Put this into your template, wrapping the Low Replace tag around your body field.
{exp:low_replace
find="[say_hello]|[say_goodbye]"
replace="{gv_hello}|{gv_goodbye}"
multiple="yes"
}
{body}
{/exp:low_replace}
5) It should output this into your browser:
Hello
Nice to see you.
Goodbye
Obviously, this is a really simple example. You can put full blown HTML into your global variable. For example, we've used that to render a complex, interactive graphic that isn't editable but can be easily dropped into a page by any editor.
Unfortunately, due to parse order issues, EE tags won't work inside Global Variables. If you need EE tags in your short code output, you'll need to use Low Variables addon instead of Global Variables.
Continued from the comment:
Do you have examples of the kind of shortcodes you want to support/include? Because i have doubts if controlling the page-layout from a text-field or wysiwyg-field is the way to go.
If you want editors to be able to adjust layout or show/hide extra parts on the page, giving them access to some extra fields in the channel, is (imo) much more manageable and future-proof. For instance some selectfields, a relationship (or playa) field, or a matrix, to let them choose which parts to include/exclude on a page, or which entry from another channel to pull content from.
As said in the comment: i totally understand if you want to replace some #foo# tags with images or data from another field (see other answers: nsm-transplant, low_replace). But, giving an editor access to shortcodes and picking them out, is like writing a template-engine to generate ee-template code for the ee-template-engine.
Using some custom fields to let editors pick and choose parts to embed is, i think, much more manageable.
That being said, you could make a plugin to parse the shortcodes from a textareas content, and then program a lot, to fetch data from other modules you want to support. For channel entries you could build out of the channel data library by objectiveHTML. https://github.com/objectivehtml/Channel-Data
I hear you, I too miss shortcodes from WP -- though the reason they work so easily there is the ubiquity of the_content(). With the great flexibility of EE comes fewer blanket solutions.
I'd suggest looking at NSM Transplant. It should fit the bill for you.
There is also a plugin called Shortcode, which you can find here at
Devot-ee
A quote from the page:
Shortcode aims to allow for more dynamic use of content by authors and
editors, allowing for injection of reusable bits of content or even
whole pieces of functionality into any field in EE
I've been trying to make something visible only on certain entry_id in expressionengine
{if entry_id="33"}
... show certain content
{/if}
is this even possible in eemcs?
thanks
Sure - but you need to use the {entry_id} variable within a tag pair that provides that variable. For example within a {exp:channel:entires} tag pair.
If you're using url_titles in the URI you may want to think about using segment variables instead. For example:
{if segment_2 == "blog-post"} You're on a blog post{if}
This is what's referred to as a simple conditional in EE, and it's fast enough.
One very important thing to remember in EE is that the standard if:else/else:if routine of an advanced conditional can be very slow, primarily because EE renders all of the code segments and then works its if:else magic. If you find yourself testing many ids or groups, this slows the site down proportionally. In fact, sometimes EEs parse order can stop if:else from functioning entirely.
Instead, consider Mark Croxton's Switchee, a fantastic free plugin that lets you have as many conditions, even nested conditions, without slowdown. It parses just the conditions, then when triggered, is smart enough to descend and run the right code segment:
I know this sounds crazy, but I need to show some post information outside of the loop in the expression engine channel module. Is this possible?
You could use EE's SQL Query template tags (if you know, or have access to the database table names and know what to look for in the database):
http://expressionengine.com/user_guide/modules/query/index.html
Basically, you'd output only what you need - it doesn't have to belong to a channel, or anything specific. The one kicker is that you'd have to know the basics of SQL syntax, but if you have a small working knowledge of it, you can do tons of additional things with it.
If you're not keen on SQL, you could simply embed a template within the template that you're working on. Here's a simple example that assumes you're editing the index and meta templates inside of a template group called 'news':
index template contents:
{exp:channel:entries channel="news"}
<div class="entry">
<h1>{title}</h1>
<div class="content">{body}</div>
{embed="news/meta" this_entry_id="{entry_id}"}
</div>
{/exp:channel:entries}
meta template contents:
{exp:channel:entries channel="news" dynamic="no" limit="1" entry_id="{embed:this_entry_id}"}
<div class="meta">
<p>{entry_date}</p>
<p>{author}</p>
</div>
{/exp:channel:entries}
As you can see, the index template is embedding the meta template. Note that we're passing a parameter to the meta template so that it knows which entry ID to print information about. If you're unfamiliar with EE's template embedding feature, you can read more about it in the EE docs. Embedding templates in other templates is a great way to access the {exp:channel:entries} loop multiple times.
There's an add-on called MX Jumper that allows you to "set" a variable from inside your entries loop and then "get" it elsewhere in the template (before or after in the HTML loop doesn't matter because it parses later).
Alternatively, the approach that's all the rage now is to use the add-on Stash to store any and all elements you need to use distinctly as stash variables that you set and then get - similar to the above, except that once you set them, getting them has to happen at a later parsing stage. The beauty of this approach is stash will store the "set" variables for reuse either at a user or site level, and you can determine what the expiry period is - which then results in better performance. When you apply this broadly using the "template partials" mindset, you can store everything with stash, and then call them into a small number of wrapper templates. This makes it possible to use stash to set, for example, your entry title, then get it three separate times in the wrapper template without any additional load - no need for separate loops within your template - one loop to set the variable, and then you can call that variable as needed in your template - it's kind of like creating global variables on the fly.
I would also suggest looking at Stash.
What's the best way to escape data from Models or Controllers to easily and safely display them in views. It seems kind of overkill to use html::specialchars($varname) for every data variable. It can also cause problems if a programmer forgets to "escape" data.
I've also encountered problems escaping ORM objects within loops.
I wrote the Twig module gimpe has suggested and by default it automatically escapes all data. You might also want to look into Kostache. It's a class based view system that does automatic escaping.
Regarding your comment:
Is there a way to do this directly from the Model
You don't want to escape the data here because HTML escaped data doesn't make sense in all output formats, eg: JSON and XML.
Do the escaping at the view level.
One way to achieve that is using a templating engine like Twig for the views. (see KO3 module http://github.com/ThePixelDeveloper/kohana-twig)
Then you simply need to load the Escaper extension:
Twig_Extension_Escaper: Adds automatic output-escaping and the possibility to escape/unescape blocks of code.
Ref.: http://www.twig-project.org/book/03-Twig-for-Developers