SilverStripe loop through hidden pages - hidden

How do I iterate only through all hidden pages in SilverStripe?
$Children excludes hidden pages. $AllChildren includes all pages. Is there a way to include only hidden pages?

We can write a function to return only the hidden children like this:
public function HiddenChildren() {
return $this->AllChildren()->filter('ShowInMenus', false);
}
Then in our template we can loop through the hidden children like this:
<% loop $HiddenChildren %>
$Title
<% end_loop %>

Well, a simple if in the template might do the trick:
<% loop $AllChildren %>
<% if not $ShowInMenus %>
$Title
<% end_if %>
<% end_loop %>
See https://docs.silverstripe.org/en/3.1/developer_guides/templates/syntax/#negation

Related

How to include a variable inside <% include > in a template ejs file?

I have a list of files in a folder that I need to serve inside the parent as a child template. I would like to do something like this:
<% var noScriptBody = 'message-scriptless.ejs' %>
<% include noScriptBody %>
or <%include <%= noScriptBody %>/message-scriptless' %> where <%= noScriptBody %> are the specific child template to include.
For example, I want to include <% include carousel/message-scriptless %> and <% include modal/message-scriptless %> where the path is variable ['carousel', 'modal', etc]
You can include dynamic template like this
for ex. your array passed is pathArray = ['carousel', 'modal', etc]
<% for (const path in pathArray) { %>
<%- include(path +'/message-scriptless.ejs') %>
<% } %>
Here, we iterate through the pathArray & include message-scriptless.ejs from each folder as shown in code above
Please correct me if I misunderstood your requirements
For an example, you can look at this code below: index.ejs
<!-- Only show text -->
<% var noScriptBody = 'message-scriptless' %>
<%= noScriptBody %>
<!-- Show template -->
<% var noScript = 'message-scriptless' %>
<%- include(noScript) -%>
<!-- Show template `message-scriptless` from `carousel` directory -->
<% var carouselMessageSciptLess= 'carousel/message-scriptless' %>
<%- include(carouselMessageSciptLess) -%>
Make sure in the same directory, you've a file message-scriptless.ejs.
Updated: For mapping your variable, you can use this code below:
<% arrayPath.forEach(function(path){
include(path + '/message-scriptless');
}) %>;
From code above, this is an example directory structure:
src > app.js
views > index.ejs
views > message-scriptless.ejs
views > carousel > message-scriptless.ejs
package.json
For more information about this ejs, you can read this documentation.
For an example, you can look at my codeSandbox: https://codesandbox.io/s/example-ejs-app-mhgrh
I hope it can help you.

how to iterate over all strings in a single record

I have a model called train that has 240 strings in it. Each string is simply named S1 through S240. I am wondering if there is a way to iterate over each string in a single record. I have a view that displays the strings. Some of the strings will have something in them and some will be empty and I just want to display the ones that are not empty in view. So I need an iterator or something to check each one and see if it is empty or not and display it if it's not empty.
I can do it using this:
<% if #train.s1 != nil then %>
<%= #train.s1 %><br>
<% end %>
Obviously I don't want to do that for 240 strings.
You probably can do something like iterating over the model's attributes.
<% #train.attributes.each do |attr_name, attr_value| %>
<% !if attr_value.blank? %>
<%= attr_value %>
<% end %>
<% end %>
This won't really work for you if you have more attributes than just those strings. Why don't you work with an association? Train has_many Strings and String belongs_to Train. So you could then iterate over #train.strings.each?
well in that case you can do like
<% (1..240).each do |index| %>
<% if #train.try("s#{index}") != nil then %>
<%= #train.try("s#{index}") %><br>
<% end %>
<% end %>

How to make a category disapear if there are no elements?

Ok guys, I have to make a list of items, they have a category. I'm Listing by Categories, however I don't want to show the category title unless there are items that belong there. I'm having trouble doing it.
<% #categorias.each do |categoria| %>
<h3> <%= categoria.categoria_pt %></h3>
<% #pratos_precos.each do |pratos_preco| %>
<% if #pratos.find(pratos_preco.prato_id).categoria_pratos_id.to_s == categoria.id.to_s %>
i want something like this:
if there is a prato_preco who's prato_id matches a prato_id who's categoria_pratos_id matches categoria_id
Solved it :)
<% #pratocategorias = #pratos.where("categoria_pratos_id = ?", categoria.id) %>
<% #pratocategorias.each do |pratocategoria|%>
<% #pratosprecos = #pratos_precos.where("prato_id = ?", pratocategoria.id) %>

Silverstripe loop

<%loop $Video.Limit(4) %><% end_loop %>
<%loop $Video.Limit(5,9) %><% end_loop %>
Two divs are being used to display the data,the above code is not working.
Any help is accepted.
as #Zauberfisch stated here you need to use limit(4) (note the lowercase) in your template.
Another problem is the missing space between <% and loop.
Assuming $Video is some kind of SS_List (ArrayList or DataList), you could try
//show the first 4 videos
<% loop $Video.limit(4) %>$Title <% end_loop %>
//gets the next 9 videos, offset is 5
<% loop $Video.limit(9,5) %>$Title <% end_loop %>
See API docs for limit

Conditions in underscore.js templates

How can we check a condition in underscore and print accordingly?
Sample code.
<% if(status==1){ %>
<%= status %>
<% } %>
Is there a way to remove the overlapping %> and <%= ??
I am a php developer and the above code in php would be :
<?php
if($status==1){
echo $status;
}
?>
Is there a way to echo in underscore like "echo"?
yes, try with print();
like:
<% if(status===1) {
print(status);
} %>
docs: http://underscorejs.org/#template