Jump to:

23361 Posts in 18124 Topics by 2862 members

General Questions

SilverStripe Forums » General Questions » Prev/Next when ordered by DATE?

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1
Go to End
Author Topic: 334 Views
  • neilcreagh
    Avatar
    Community Member
    90 Posts

    Prev/Next when ordered by DATE? Link to this post

    Hi, I have news articles ordered by their date, all working fine.

    static $db = array(
       'Date' => 'Date',
       );

    But on each article I want a next/previous buttons, but this function below isn't working for me, can anyone see where I've gone wrong?

    function NextArticle() {
    return DataObject::get("NewsArticle", "Date < ($this->Date)", "", "", "1");
    }

    function PreviousArticle() {
    return DataObject::get("NewsArticle", "Date > ($this->Date)", "", "", "1");
    }

    On my ArticlePage template I'm using:

    <% control PreviousArticle %><a class="prev" href="$Link"><</a><% end_control %>
    <% control NextArticle %><a class="next" href="$Link">></a><% end_control %>

  • Theak
    Avatar
    Community Member
    2 Posts

    Re: Prev/Next when ordered by DATE? Link to this post

    Assuming NewsArticle is a DataObject and not a SiteTree/Page subclass, you can try this:

    public function NextArticle() {
    $next = DataObject::get("NewsArticle","NewsArticle.Date <= '{$this->Date}' AND NewsArticle.ID <> {$this->ID}","NewsArticle.Date.DESC, NewsArticle.ID ASC","","0,1");
    if ($next && $next->exists()) {
    return $next->First();
    }
    return null;
    }

    public function PreviousArticle() {
    $prev = DataObject::get("NewsArticle","NewsArticle.Date >= '{$this->Date}' AND NewsArticle.ID <> {$this->ID}","NewsArticle.Date.ASC, NewsArticle.ID DESC","","0,1");
    if ($prev && $prev->exists()) {
    return $prev->First();
    }
    return null;
    }

    We need to use '<=' and not '<' for checking the date in the 'NextArticle' function because two articles may have been posted on the same date and we don't want to skip over those. We need to exclude the current article from the list though, hence the 'NewsArticle.ID <> {$this->ID}' clause.

    I'd also recommend escaping the bracket in your template code like this:

    <% if PreviousArticle %>

    <% control PreviousArticle %>

    <a class="prev" href="$Link">&lt;</a>

    <% end_control %>

    <% end_if %>

    <% if NextArticle %>

    <% control NextArticle %>

    <a class="next" href="$Link">&gt;</a>

    <% end_control %>

    <% end_if %>

  • neilcreagh
    Avatar
    Community Member
    90 Posts

    Re: Prev/Next when ordered by DATE? Link to this post

    Thank you so much for replying Theak. NewsArticle is in fact a Page subclass. Also, I don't understand why my code doesn't work, is there anything wrong with it? Good advise though, what changes would need to be made to this in order for it to work with the SiteTree? Changing all instances of NewsArticle.Date to just Date ?

    I'm using Silverstripe 3 by the way.

  • Theak
    Avatar
    Community Member
    2 Posts

    Re: Prev/Next when ordered by DATE? Link to this post

    The main thing I spotted was that you weren't quoting the date in the 'NextArticle' and 'PreviousArticle' functions. The DataObject::get() syntax is deprecated in SS 3, so try this instead:

    public function NextArticle() {
    return NewsArticle::get()->filter("Date:GreaterThan:Negation",$this->Date)->exclude("ID",$this->ID)->sort(array('Date' => 'DESC', 'ID' => 'ASC'))->limit(1)->first();
    }

    public function PreviousArticle() {
    return NewsArticle::get()->filter("Date:LessThan:Negation",$this->Date)->exclude("ID",$this->ID)->sort(array('Date' => 'ASC', 'ID' => 'DESC'))->limit(1)->first();
    }

    The <% control %> block is also deprecated in SS 3. Try this in your templates instead:

    <% if $PreviousArticle %>

    <% with $PreviousArticle %>

    <a class="prev" href="$Link">&lt;</a>

    <% end_with %>

    <% end_if %>

    <% if $NextArticle %>

    <% with $NextArticle %>

    <a class="next" href="$Link">&gt;</a>

    <% end_with %>

    <% end_if %>

  • neilcreagh
    Avatar
    Community Member
    90 Posts

    Re: Prev/Next when ordered by DATE? Link to this post

    Thanks so much!
    Your code works great, I just had to switch the Previous/Next functions 'GreaterThan/LessThan' and change the sort order a little bit ('next' being older articles).

    public function PreviousArticle() {
       return NewsArticle::get()->filter("Date:GreaterThan:Negation",$this->Date)->exclude("ID",$this->ID)->sort(array('Date' => 'ASC', 'ID' => 'ASC'))->limit(1)->first();
       }

       public function NextArticle() {
       return NewsArticle::get()->filter("Date:LessThan:Negation",$this->Date)->exclude("ID",$this->ID)->sort(array('Date' => 'DESC', 'ID' => 'ASC'))->limit(1)->first();
       }


    This is working perfectly for me - thank you.

    334 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.