Creating article pagination - silverstripe

Hi I'm using silverstripe 2.4.7 and I'm having difficulty getting the pagination to work. I've created a function in my page.php to get the latest articles like so
function AllNewsPosts($num=1) {
$news = DataObject::get_one("NewsHolder");
return ($news) ? DataObject::get("NewsEntry", "ParentID > 0", "Date DESC", "", $num) : false;
}
Then when i put this function into the control and pagination tags one article shows up however the links to the concurrent articles do not work - essentially the pagination is not working and I'm not sure how to fix it
<% if AllNewsPosts %>
<% control AllNewsPosts %>
<div class="event">
<h2>$MenuTitle |<span class="date"> $Date.Time $Date.Long</span></h2>
<p>$Content.FirstParagraph</p>
See more about this event
</div>
<% end_control %>
<% else %>
<div class="no-entry">'There are no entries'</div>
<% end_if %>
<% if AllNewsPosts.MoreThanOnePage %>
<div id="PageNumbers">
<p>
<% if AllNewsPosts.NotFirstPage %>
<a class="prev" href="$AllNewsPosts.PrevLink" title="View the previous page"><span class="yellow-background">Prev</span></a>
<% end_if %>
<span>
<% control AllNewsPosts.PaginationSummary(0) %>
<% if CurrentBool %>
<span class="current">$PageNum</span>
<% else %>
<% if Link %>
$PageNum
<% else %>
…
<% end_if %>
<% end_if %>
<% end_control %>
</span>
<% if AllNewsPosts.NotLastPage %>
<a class="next" href="$AllNewsPosts.NextLink" title="View the next page"><span class="yellow-background">Next</span></a>
<% end_if %>
</p>
</div>
<% end_if %>
Any help is much appreciated

Note: The following answer is for Silverstripe 2.4. This should not be used for Silverstripe 3.0+ sites. From 3.0 and onwards the PaginatedList object makes pagination much easier.
You are not setting a limit on how many entries to retrieve in your query, or where to start from.
The following tutorial explains how to apply pagination to a set of data objects exactly as you are trying to do:
http://www.ssbits.com/tutorials/2010/paginating-a-filtered-dataobjectset/
Here is an attempt at altering your function to include limit and start as needed for pagination:
PHP
function AllNewsPosts() {
if(!isset($_GET['start']) || !is_numeric($_GET['start']) || (int)$_GET['start'] < 1)
{
$_GET['start'] = 0;
}
$SQL_start = (int)$_GET['start'];
$newsEntries = DataObject::get('NewsEntry', '', 'Date DESC');
$doSet = new DataObjectSet();
foreach ($newsEntries as $newsEntry) {
if ($newsEntry->canView()) {
$doSet->push($newsEntry);
}
}
$doSet->setPageLimits($SQL_start, 10, $doSet->Count());
return $doSet;
}
Note the above will display 10 items per page. You can change this to however you need per page.

Related

How compare date and current date in Silvrerstripe template?

In Silverstripe template I need to compare variable $date_ok with current date like this : if($date_ok < date("j, n, Y") {...};
<% loop $IzdMat %>
<tr>
<td>$num</td>
<td>$sert_otip </strong> <br>Valid from $date_start till
$date_ok</td>
<% if $date_ok < ****** %>
..............
<% end_if %>
.......
What I have to write insted of ****** ?
You can add a method to the DataObject rather than trying to do complicated logic in the templates. This is assuming that date_ok is a date field defined in the $db array.
class IzdMat extends DataObject {
public function IsDateOk() {
$today = date("Y-m-d");
return (strtotime($today) < strtotime($this->date_ok));
}
}
Then in your template.
<% loop $IzdMat %>
<tr>
<td>$num</td>
<td>$sert_otip </strong> <br>Valid from $date_start till
$date_ok</td>
<% if $IsDateOk %>
..............
<% end_if %>
</tr>
<% end_loop %>

sqlite method return query output of rails console in render proccess

Specs :
Ubuntu 16.04 LTS i686
, Ruby 2.1.5 , Rails 4.2.7 , sqlite 3 , devise 4.3
when I loop through each user in users , it's rendering the users + a query output from rails console.
Devise model name : User .
controller name: users.
I tried this code:
users_controller.rb
def index
#users = User.all()
end
routes.rb
resources :users, only: [:index, :show]
views/users/index.html.erb
<%= #users.each do |user| %>
<%= link_to user do %>
<li>
<img src="images/avatar.jpg" alt="">
<div class="user_overview">
<h2><%= user.title %></h2>
<p class="posts_count">1 post</p>
</div>
</li>
<% end %>
<% end %>
In your view, just remove = from <%= #users.each do |user| %>.
It will become like:
<% #users.each do |user| %>
<%= link_to user do %>
<li>
...
...
...
...
</li>
<% end %>
<% end %>
= in erb is used for displaying the content that's why your loop is displaying the enumerator.
Read more details on Expression Printing Tags

SilverStripe arithmetic in template

I want to do a simple arithmetic operation in a .ss template.
<% loop $Images %>
<img src="$Link" alt=""/>
<% $Pos == 4 %>
and {$TotalItems - 4} more foto's
$Break
<% end_if %>
<% end_loop %>
For example I would want to output
and 10 more foto's
But the best I can get is
and 14 - 4 more foto's
I know I can make a function, which works for now, but can I do arithmetic operations in the template?
You could do it like this.
At first you limit the images to the amount you would like to display. After that you loop over the same set with an offset of x (4) and check if there's more. If so, output the amount of remaining images.
<% loop $Images.Limit(4,0) %>
<img src="$Link" alt=""/>
<% end_loop %>
<% if $Images.Limit(9999,4) %>
and $Images.Limit(9999,4).Count more foto's
<% end_if %>
the code is untested but should work.
Edit
I think "real" arithmetic is not possible by default. You'll need to write a custom function to do this.

Using article frontmatter when iterating in Middleman blog

Not the best title, but I'm honestly not sure on how to properly explain what I'm looking for help for.
So I'm using Middleman blog to well create my blog. Anyways, I'm using frontmatter to pass css that change the look of each page individually. I'm using 4 variables, link_color, text_color, bg_link. So what I want to do is reuse that same frontmatter information in the layout.html.erb file.
So the layout.html.erb is the standard
<% if paginate && num_pages > 1 %>
<p>Page <%= page_number %> of <%= num_pages %></p>
<% if prev_page %>
<p><%= link_to 'Previous page', prev_page %></p>
<% end %>
<% end %>
<% page_articles.each_with_index do |article, i| %>
<li class="article_summary">
<h1><%= link_to article.title, article, id: "#{i}" %></h1>
</li>
<% end %>
<% if paginate %>
<% if next_page %>
<p><%= link_to 'Next page', next_page %></p>
<% end %>
<% end %>
What I'm trying to do is for each article within that iterator is if the article has bg_color frontmatter then use that and change the color of the article.title if not, then do nothing. Currently if I try with something like:
<style>
<% if article.data.bg_color? %>
.article_summary a#<%= i %>{
color: rgb(<%=article.data.bg_color %>);
}
<% end %>
</style>
I'm doing it this way because my blog lives on Github.
Currently it works, but since it's just a simple iteration it gives every article that same color and not on a per article basis. So I'm trying to figure out the best way to utilize the index as some sort of id so that they're targeted individually.
Perhaps changing the li from a class to an id consisting of the index, but then I won't be able to apply a global style from the scss in the stylesheet folder no?
I've found a dirty method that works.
<% page_articles.each_with_index do |article, i| %>
<li class="article_summary" id="test_<%=i %>">
<h1><%= link_to article.title, article %></h1>
<style>
<% if article.data.bg_color? %>
#test_<%=i%> a{
color: <%=article.data.bg_color %>;
}
<% end %>
</style>
</li>
<% end %>
Pretty much added "test_" to the id (before I was just doing the index itself) and viola!

Silverstripe: Excluding current page from list of the parent's children

Using Silverstripe's "ChildrenOf" syntax, I've been successfully able to list all children of a page's parent. It's being used in a "see also" style list on a page.
I'd like to exclude the current page from the list but unsure how to determine which is the same as the current page, as within the control loop I'm in the parent's scope. Any ideas? Here's a pseudocode of what I'm doing:
<% control ChildrenOf(page-url) %>
<!-- Output some stuff, like the page's $Link and $Title -->
<% end_control %>
there's a built-in page control for this, so to exclude the current page from your list:
<% control ChildrenOf(page-url) %>
<% if LinkOrCurrent = current %>
<!-- exclude me -->
<% else %>
<!-- Output some stuff, like the page's $Link and $Title -->
<% end_if %>
<% end_control %>
see http://doc.silverstripe.org/sapphire/en/reference/built-in-page-controls#linkingmode-linkorcurrent-and-linkorsection
UPDATE
as you mentioned in your comment below that you'd like to use the $Pos control, you need to filter the dataobjectset before iterating over it.
add the following to your Page_Controller class:
function FilteredChildrenOf($pageUrl) {
$children = $this->ChildrenOf($pageUrl);
if($children) {
$filteredChildren = new DataObjectSet();
foreach($children as $child) {
if(!$child->isCurrent()) $filteredChildren->push($child);
}
return $filteredChildren;
}
}
then replace 'ChildrenOf' in your template by 'FilteredChildrenOf':
<% control FilteredChildrenOf(page-url) %>
//use $Pos here
<% end_control
In Silverstripe 3.1 you can use a method like this -
<% loop $Parent.Children %>
<% if $LinkingMode != current %>
<!-- Output some stuff, like the page's $Link and $Title , $Pos etc -->
<% end_if %>
<% end_loop %>
This way you can list all parent's children pages.
See https://docs.silverstripe.org/en/3.1/developer_guides/templates/common_variables/

Resources