DS Filtering: next article / previous article
This is an open discussion with 79 replies, filed under Troubleshooting.
Search
Simply uploading the files didn’t work for me. But I created four empty datasources using the frontend and then was able to edit the created files.
I’m was struggeling a bit with adapting the SQL to my setup - as I’m not using the standard Symphony structure (meaning articles). It just came to my mind what the meaning of the tables had to be:
symentriesdata26.local —> Publishing Date symentriesdata30.value —> Published Checkbox
I will try to adapt the code tomorrow - as I’m really tired right now ;) Will report back on this…
That’s correct. Sorting on date
to get the next and previous articles and filtering on publish
to show show only published articles.
I don’t understand why just placing the files in your workspace/data-sources
folder didn’t work, unless there was a name conflict. I often duplicate a data source file, change the file name and class name and then open it in the backend data source editor and make additional changes as needed.
You were right. I’ve changed the filenames before uploading the files. This seems to be violation the convention.
Now I got it working - finally! YEAH :) Thanks big time for your help!
One strange thing I still had to fix using some XSLT was that when reaching the first/last article the prev/next datasource still contained the data of the current article instead of being empty (as one would expect). The datasource contained data even though the correspondong output-param-id I was filtering upon actually was empty?!?!
I did something like this to get rid of the self-referencing link:
<xsl:if test="(//vd-post/entry/@id != //vd-next/entry/@id)"> <a href="URL of next item">next</a> </xsl:if>
Would be interesting to know why the datasource contained any data in that case…
I only show one of the next-prev links when at the beginning or end of the entries, so I just don’t worry about the extra data in the xml.
How do you determine which one to display - i.e. whether you are viewing the first or last item?
Here is my xslt:
<div class='prev_post'> <xsl:if test="boolean($ds-prevarticleid) = true()"> <xsl:variable name="phandle" select="prevarticle/entry/title/@handle"/> <xsl:variable name="ptitle" select="prevarticle/entry/title"/> <a href="{$root}/article/{$phandle}" title="{$ptitle}"><< Previous article</a> </xsl:if> </div> <div class='next_post'> <xsl:if test="boolean($ds-nextarticleid) = true()"> <xsl:variable name="nhandle" select="nextarticle/entry/title/@handle"/> <xsl:variable name="ntitle" select="nextarticle/entry/title"/> <a href="{$root}/article/{$nhandle}" title="{$ntitle}">Next article >></a> </xsl:if> </div>
Thanks man! I actually didn’t know how to access the output params in XSLT. I seriously have to stack up my XSLT-skills - besides all the other stuff ;)
Have a nice weekend!
Nice thread.
I am facing the exact same problem.
I need a previous article
and a next article
button underneath each of my articles.
I wonder if there's a more elegant solution to the problem in Symphony 2.2?
I'm a bit reluctant to create two extra data sources just for this tiny bit of functionality...
Would be glad if someone could help.
The approach I described above actually takes four data sources but costs very little in overhead because they involve only three entries per page. Anyhow, I agree that this approach clutters up the backend design of your site, so I have smashed it all into one custom data source. If you want to use this approach just copy the following into a file named data.nextprevarticle.php, place it in your workspace/data-sources folder and add it to your article page. Your article DS will need to output System ID as a parameter. If your single article DS is not named Article you will have to do a little editing. You will also have to change the table numbers to agree with your article section design.
<?php Class datasourcenextprevarticle extends Datasource{ public function __construct(&$parent, $env=NULL, $process_params=true){ parent::__construct($parent, $env, $process_params); $this->_dependencies = array('$ds-article'); } public function about(){ return array( 'name' => 'NextPrevArticle', 'author' => array( 'name' => 'Carson Sasser', 'website' => 'http://tech.carsonsasser.com', 'email' => 'sassercw@cox.net'), 'version' => '1.0', 'release-date' => '2011-03-23T21:05:11+00:00'); } public function allowEditorToParse(){ return false; } // Gets the previous and next articles given a current article (ds-article contains // the entry_id of the current article and comes from the article data source). public function grab(&$param_pool=NULL){ $result = new XMLElement('next_prev_article'); // Get the entry_id and date (table 26) of the current article. $entry_id = (int)$param_pool['ds-article'][0]; $sql = "SELECT `local` FROM `sym_entries_data_26` WHERE `entry_id` = $entry_id LIMIT 1"; $entry_date = $this->_Parent->Database->fetchVar('local', 0, $sql); // Get the entry_id of the next published (table 30) article. $sql = "SELECT t1.`entry_id` FROM `sym_entries_data_26` AS t1 LEFT JOIN `sym_entries_data_30` AS t2 ON t1.entry_id = t2.entry_id WHERE t1.`local` > $entry_date AND t2.value = 'yes' ORDER BY t1.`local` ASC LIMIT 1"; $next_article_id = $this->_Parent->Database->fetchVar('entry_id', 0, $sql); // Get the title and handle (table 23) of the next article and add them to the XML. if ($next_article_id) { $sql = "SELECT handle,value FROM sym_entries_data_23 WHERE entry_id = $next_article_id LIMIT 1"; $row = $this->_Parent->Database->fetchRow(0, $sql); $next = new XMLElement('next', $row['value']); $next->setAttributeArray(array('entry_id' => $next_article_id, 'handle' => $row['handle'])); $result->appendChild($next); } // Get the entry_id of the previous published (table 30) article. $sql = "SELECT t1.`entry_id` FROM `sym_entries_data_26` AS t1 LEFT JOIN `sym_entries_data_30` AS t2 ON t1.entry_id = t2.entry_id WHERE t1.`local` < $entry_date AND t2.value = 'yes' ORDER BY t1.`local` DESC LIMIT 1"; $prev_article_id = $this->_Parent->Database->fetchVar('entry_id', 0, $sql); // Get the title and handle (table 23) of the previous article and add them to the XML. if ($prev_article_id) { $sql = "SELECT handle,value FROM sym_entries_data_23 WHERE entry_id = $prev_article_id LIMIT 1"; $row = $this->_Parent->Database->fetchRow(0, $sql); $prev = new XMLElement('previous', $row['value']); $prev->setAttributeArray(array('entry_id' => $prev_article_id, 'handle' => $row['handle'])); $result->appendChild($prev); } return $result; } }
Here is an example of the XML:
<next_prev_article> <next entry_id="9" handle="the-next-article-title">The Next Article Title</next> <previous entry_id="7" handle="the-previous-article-title">The Previous Article Title</previous> </next_prev_article>
And the XSLT I use to display the links:
<xsl:template match="next_prev_article"> <div class='prev_post'> <xsl:if test="previous"> <a href="{$root}/article/{previous/@handle}" title="{previous}"><< Previous article</a> </xsl:if> </div> <div class='next_post'> <xsl:if test="next"> <a href="{$root}/article/{next/@handle}" title="{next}">Next article >></a> </xsl:if> </div> </xsl:template>
This is not going to be more efficient computationally but it is more compact and straight-forward design-wise.
More details here.
Hey wisolman and vladG,
Thanks for your help. I played a bit with both your suggestions and came to the conclusion that in my particular case it may be even more user-friendly to just use one button labelled next project.
I just need this functionality to give my visitors a chance to browse through my portfolio of web design projects. The more I think about it the more I like the idea. Why would anyone ever hit previous project anyway? It just doesn't make any sense!
So all I needed was another datasource with earlier than {$ds-project}
in the date filter. That's it!
Hello everyone!
I’ve tried implementing vladG’s solution, but I’m not able to make it working since my “next-project” datasource throws me an error:
I guess it has to do with the fact the {$ds-project} parameter output of the Order Entries Field is not a mere number but a number enclosed in a span tag:
<ds-project> <item handle="3"><span class="order">3</span></item> </ds-project>
Is there a way to select the mere number inside the span tag by means of the datasource filter? At the moment my filter value is:
mysql: value > {$ds-project}
Thanks!
EDITED
I‘ve followed the instructions posted by the mighty Nick Dunn here, adding the following method at the end of the “extensions/order_entries/fields/field.order_entries.php” file:
public function getParameterPoolValue(Array $data){ return $data['value'];
}
and now the parameter output of the Order Entries Field is a mere number, thus vladG’s solution seems to work fine!
thus vladG’s solution seems to work fine!
yeah, it happens I'm using it all the time :)
@theBigMandarino
I know this error that you're encountering. What version of Order Entries are you using? I remember @nick fixed this in later versions.
@vladG
Indeed, it works like a charm! ^_^ (I wrote “it seems to work” instead of ”it works” because – since I’m not able to code PHP – usually I’ve always accidents with the customization of extensions…)
I’ve started from scratch a new project so I’ve downloaded the very last version of Order Entries from Github, that is the 1.9.6 one.
I made all the DS according to what VladG said. Made no difference in my xslt and now I get a page not found error message.
Can anyone help me figure out what went wrong here ?
@roelof
I need your XSLT and snapshots with your Datasources. Make some print screens or something, please.
Oke,
My XSLT can be found here : XSLT
The DS :
Normal one : Normal DS for displaying articles Article_details : Article details DS previous : previous DS next : next DS
On Article Details datasource you are filtering for {titel}
instead of {$titel}
.
Need to see the XML after you make this modification.
I did the change and found where the page not found come from. It was the title in the filtering of the display-articles DS. So here you can find the xml : XML
Create an account or sign in to comment.
Just put all four files in
workspace/data-sources
and they should show up in your backend. Then, except for the custom data sources, you should be able to edit them to fit your needs. You will have to use a text editor to change the custom data sources. Let me know if you need further help.