Search

Sorry, I just don't follow at all :(

On my workblog we are using the Union Datasource extension to combine a Twitter and News feed. This is then paginated by 10, so there will be 10 'entries' on a page ordered chronologically. Sometimes there will be 3 News articles, and 7 Tweets, other times there will be 6 News articles and 4 Tweets. Hell sometimes we've even had just 10 Tweets.

The number '10' comes from our datasource, which says paginate on every '10' articles. Do you have a datasource?

Ah, I see. So you want to display a certain amount of text. Display a single one if it's just one long article or display more than one if they are shorter.

In essence: The number of words on one page should aways stay within the same range, no matter how many articles.

@phoque: that's my understanding, and I think @roelof was wanting to set which entries are displayed in what quantities manually. I imagine it's possible on a more automated basis, though, depending on actual criteria.

Correct but the certain amount is not a fixed number. When I display articles I will look and try to determine how full a page is.

Alright, now we're making progress.

Next question: Do you want some sort of "continuous pagination" or do you want to display only articles of a certain month and have only those few grouped to your liking?

@phoque : I think the last one. But I have no clue how continous pagination works with for example a menu which the user chooses a month to read.

Alright, monthly view it is then. That should be easy.

First we need to find a way to save those page breaks. I suggest using a simple checkbox: Every article that has it checked will appear on a new page, simple as that.

  1. Add a Checkbox to your Articles section. Name it "Breakpoint" or "Creates a new page within it's month" or something that makes sense to you
  2. Make sure your Data Source only selects articles from a given month (it should already)
  3. Disable pagination in that data source
  4. Include that field in the returned fields of your DS

Imagine our template for displaying the article looks like

<xsl:template match="entry">
    <h2><xsl:value-of select="title"/></h2>
    <xsl:copy-of select="text/*"/>
</xsl:template>

To make it work we need to tinker with the XSLT a little bit: Instead of simply fetching the articles from the XML like

<xsl:apply-templates select="articles/entry" />

we need to first fetch the ones that have that checkbox selected:

<xsl:apply-templates select="articles/entry[breakpoint = 'yes']" mode="pagegroup" />

But among those we want to be able to control wich one we get:

Add a parameter page to your Symphony-page, initialize it at the very top of your stylesheet using

<xsl:variable name="page" select="'1'" />

and change the line we had before to

<xsl:apply-templates select="articles/entry[breakpoint = 'yes'][position() = $page]" mode="pagegroup" />

Now we're able to select the first article of each group while the group can be chosen using page parameters. To continue we need to find all articles that belong to that group:

<xsl:template match="entry" mode="pagegroup">
    <xsl:apply-templates select=". | following-sibling::entry[not(breakpoint = 'yes') and preceding-sibling::entry[breakpoint = 'yes'][1] = current()]" />
</xsl:template>

The Xpath looks a bit funky but it mainly does the following: It selects the current node and each following siblings that don't have breakpoint set to yes. That would return all siblings for all groups so among those we need to select only the ones whose directly preceding sibling with breakpoint set to yes is the current node.

So essentially, you should end up with XSLT like

<?xml version='1.0' encoding='utf-8'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:variable name="page" select="'1'" />

    <xsl:template match="data">
        <xsl:apply-templates select="articles/entry[breakpoint = 'yes'][position() = $page]" mode="pagegroup" />
    </xsl:template>

    <xsl:template match="entry" mode="pagegroup">
        <xsl:apply-templates select=". | following-sibling::entry[not(breakpoint = 'yes') and preceding-sibling::entry[breakpoint = 'yes'][1] = current()]" />
    </xsl:template>

    <xsl:template match="entry">
        <h2><xsl:value-of select="title"/></h2>
        <xsl:copy-of select="text/*"/>
    </xsl:template>

</xsl:stylesheet>

Now this code does have a problem: It requires you to set the first entry of each month to have breakpoint set to yes. This could be circumvented with a few changes but we'll solve this once you've got this code to work.

While this doesn't implement a comfortable way of navigating pages using "next" or "previous" links you should be able to select the appropriate page by changing the parameter in the URL.

@phoque :

Thanks, I will try to make this work.I find it a pity that there is no comfortable way to make next of previuos links because these are a part of the layout.

Edit 1 : Can we make a paramater totalpages which contains the number of checkboxex which are enabled ? If so, we can easily make a next/ previous links

@phoque :

I have some problems adapting your idea. When I do it this way. I see the dates and the titles but not the text.

I have this xslt:

dagboek.xslt:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:import href="../utilities/master.xsl"/>
<xsl:import href="../utilities/dagboek-article.xsl"/>

<xsl:template match="data">
      <xsl:apply-templates select="dagboek/entry" />
</xsl:template>

</xsl:stylesheet>

And the xslt for dagboek.xsl:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

     <xsl:import href="../utilities/date-time.xsl"/>

    <xsl:template match="dagboek/entry" >
        <h3> 
        <xsl:value-of select="titel" /> 
      </h3>
      <div class="post-inner">
         <div class="date-tab">
             <span class="month">
                   <xsl:call-template name="format-date">
                   <xsl:with-param name="date" select="datum"/>
                <xsl:with-param name="format" select="'M'"/>
                   </xsl:call-template>
             </span>
             <span class="day">
                    <xsl:call-template name="format-date">
                <xsl:with-param name="date" select="datum"/>
                <xsl:with-param name="format" select="'d'"/>
                    </xsl:call-template>
             </span>
       </div>
     <xsl:apply-templates select="dagboek/entry[breakpoint = 'yes']" mode="pagegroup" />
 </div>
</xsl:template>

<xsl:template match="entry" mode="pagegroup">
        <xsl:apply-templates select=". | following-sibling::entry[not(breakpoint = 'yes') and preceding-sibling::entry[breakpoint = 'yes'][1] = current()]" />
</xsl:template>

<xsl:template match="entry">
        <h2><xsl:value-of select="title"/></h2>
        <xsl:copy-of select="tekst/*"/>
</xsl:template>


</xsl:stylesheet>   

Sorry, I can't make any sense from your XSLT. Why is there a dagboek.xslt and a dagboek.xsl? Also you seem to have simply copy and pasted some of my code without changing it to fit your XML-schema.

I find it a pity that there is no comfortable way to make next of previuos links because these are a part of the layout.

There is a builtin "comfortable way" that does the job 99% of the time: the <pagination /> element. Symphony and XSLT give you all the power to do it yourself if you see yourself in that 1%.

Can we make a paramater totalpages which contains the number of checkboxex which are enabled?

Yes, you can. I leave it up to you to find the Xpath expression that does that.

Sorry the first is dagboek.xsl and the second ust be dagboek-article.xsl

I changed the dagboek.xsl to this :

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:import href="../utilities/frontpage-article.xsl"/>
<xsl:import href="../utilities/date-time.xsl"/>

<xsl:template match="dagboek/entry" >
    <h3> 
    <xsl:value-of select="titel" /> 
  </h3>
  <div class="post-inner">
     <div class="date-tab">
         <span class="month">
               <xsl:call-template name="format-date">
               <xsl:with-param name="date" select="datum"/>
            <xsl:with-param name="format" select="'M'"/>
               </xsl:call-template>
         </span>
         <span class="day">
                <xsl:call-template name="format-date">
            <xsl:with-param name="date" select="datum"/>
            <xsl:with-param name="format" select="'d'"/>
                </xsl:call-template>
         </span>
   </div>
        <xsl:apply-templates select="dagboek/entry[nieuwe-pagina = 'yes']" mode="pagegroup" />
        <xsl:apply-templates match="tekst/*" />
 </div>
</xsl:template>

<xsl:template match="entry" mode="pagegroup">
        <xsl:apply-templates select=". | following-sibling::entry[not(nieuwe-pagina = 'yes') and preceding-sibling::entry[nieuwe-pagina = 'yes'][1] = current()]" />
</xsl:template>

</xsl:stylesheet>

Now it works only the title and date are displayed two times. One time at the beginning of a article and one time at the bottom.

Can anyone tell me how to solve this one? I also see the text "yes" appear in the first article of a month ?

I solved this one by changing the xslt to this :

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:import href="../utilities/frontpage-article.xsl"/>
<xsl:import href="../utilities/date-time.xsl"/>

<xsl:template match="dagboek/entry" >
    <h3> 
    <xsl:value-of select="titel" /> 
  </h3>
  <div class="post-inner">
     <div class="date-tab">
         <span class="month">
               <xsl:call-template name="format-date">
               <xsl:with-param name="date" select="datum"/>
            <xsl:with-param name="format" select="'M'"/>
               </xsl:call-template>
         </span>
         <span class="day">
                <xsl:call-template name="format-date">
            <xsl:with-param name="date" select="datum"/>
            <xsl:with-param name="format" select="'d'"/>
                </xsl:call-template>
         </span>
   </div>
        <xsl:apply-templates select="dagboek/entry[nieuwe-pagina = 'yes']" mode="pagegroup" />
        <xsl:apply-templates select="tekst" />
   </div>
</xsl:template>

<xsl:template match="entry" mode="pagegroup">
       <xsl:apply-templates select=". | following-sibling::entry[not(nieuwe-pagina = 'yes') and preceding-sibling::entry[nieuwe-pagina = 'yes'][1] = current()]" /> 
</xsl:template>

</xsl:stylesheet>

But as you can see it does not do what it's supposed to do. As you look at this page I enabled on the first and second article the nieuwe-pagina but still it's schowing all the articles.

My xml looks like this :

<?xml version="1.0" encoding="utf-8" ?> 
     <data> 
        <params> 
             <today>2012-02-10</today> 
             <current-time>08:58</current-time> 
             <this-year>2012</this-year> 
             <this-month>02</this-month> 
             <this-day>10</this-day> 
             <timezone>+01:00</timezone> 
             <website-name>Tamara Wobben</website-name> 
             <page-title>dagboek</page-title> 
             <root>http://test.tamarawobben.nl</root> 
             <workspace>http://test.tamarawobben.nl/workspace</workspace> 
             <root-page>dagboek</root-page> 
             <current-page>dagboek</current-page> 
             <current-page-id>7</current-page-id> 
             <current-path>/dagboek/2005/04/1/?debug</current-path> 
             <parent-path>/</parent-path> 
             <current-url>http://test.tamarawobben.nl/dagboek/2005/04/1/?debug</current-url> 
             <upload-limit>2097152</upload-limit> 
             <symphony-version>2.2.5</symphony-version> 
              <year>2005</year> 
              <month>04</month> 
              <page>1</page> 
              <cookie-username>xxxxxx</cookie-username>
               <cookie-pass>xxxxxxx</cookie-pass> 
              <site-mode>live</site-mode> 
        </params> 
       <events /> 
      <dagboek> 
          <section id="9" handle="dagboek">Dagboek</section>
          <entry id="20"> 
                <nieuwe-pagina>Yes</nieuwe-pagina> 
                <tekst mode="formatted"><p>Alvast bloed laten prikken voor de tripletest. De uitstag is dan binnen als de nekplooimeting wordt gedaan. Sinds kort kan dat in het S.M.T. in Hengelo, dus dat is mooi meegenomen. Nog niet veel mensen weten dat je in mijn buik aan het groeien bent, maar ik had het al wel tegen een vriendin verteld en het leuke was dat ik de week erna een hele stapel broeken te leen kreeg en een stapel Wij jonge ouders. Dus lees ik volop. Heerlijk om in weg te dromen en ik ben benieuwd hoe jij eruit zult zien.</p> 44 45<p>FLOAT : echo.jpg </p> 46 47<p>De hoeveelheid vocht in jouw nek is meer dan gebruikelijk, het is 3,2 mm, met alle gegevens erbij wordt een kansberekening gemaakt voor het Downsyndroom. De uitslag is een kans van 1 op 24. Het lijkt niet veel maar toch. Verslagen verlaten we het ziekenhuis en in de trein wordt het mij teveel. De uitslag en het gezeur over de manier waarop de echo was geregeld werd me teveel en wat me al heel lang niet meer was overkomen gebeurt dan toch, ik zit te huilen in de trein.</p> 48 49<p>Terug op het werk vertel ik mijn collega’s wat er is gezegd en neem dan pauze, even de honden uitlaten. Thuis schrik ik van het bericht op het antwoordapparaat. Mijn gynaecoloog, Dr. Veenstra heeft gebeld, de uitslag van de tripletest is binnen en ze wil me zo snel mogelijk spreken. Uitslag binnen, dat kon toch niet. Ik snap er niets meer van en ga eerst met de honden lopen en moed verzamelen. Dr. Veenstra is er ’s middags niet en ik word doorverbonden met Dr. Gnodde. Hij verontschuldigd zich voor het feit dat ik deze informatie over de telefoon krijg, maar het is heel belangrijk. De uitslag van de tripletest is dat er een kans is van 1 op 30 op een kindje met het Downsyndroom. Echter, samen met de nekplooimeting wordt het een kans van 1 op 3! Als ik de telefoon neerleg is de grond onder mijn voeten weggeslagen. De honden voelen mijn verdriet en zitten dicht bij me. Ik bel jouw papa en spreek met hem af dat ik hem op kom halen zodra ik rustig ben, ik heb behoorlijk zitten huilen aan de telefoon.</p> 50 51<p>Terug op het werk zien mijn collega’s al dat niet goed gaat en ik vertel wat er is. Het werk wordt onder mijn handen weggepakt en ik moet je papa bellen. Hij is er heel snel en we gaan samen naar huis, een voordeel als je in het zelfde gebouw 52werkt.</p> 
             </tekst> 
              <titel handle="nekplooimeting">Nekplooimeting </titel> 
              <datum time="00:00" weekday="5">2005-04-01</datum> 
        </entry> 
        <entry id="21"> 
           <nieuwe-pagina>Yes</nieuwe-pagina> 
           <tekst mode="formatted"><p>Er is veel gesproken over de echo, de vlokkentest en mijn angst hiervoor. Jouw papa en ik hebben besloten om het wel te doen, dan hebben we zekerheid. Ik heb het ziekenhuis gebeld en ik moet morgen naar het MST. Ik zie er als een berg tegenop.</p> 60
            </tekst> 
            <titel handle="vlokkentest">Vlokkentest ?</titel> 
             <datum time="19:16" weekday="1">2005-04-04</datum> 
          </entry> 
    </dagboek>
    </data>

Nobody who is willing to help me to make this idea from phoque work.

@roelof, can you make a screenshot of your "dagboek" datasource and post it here?

@bzeranggue : here you can find the screenshot

I am really very hesitant in explaining you "how to make my solution work" as you don't seem to understand the most basic concepts of XSLT.

The XSLT you're providing is not just missing some bits here and there but it's concept is entirely not being thought about.

Mistakes like this simply don't happen if you have at least a very basic knowledge of XSLT:

<xsl:template match="dagboek/entry">
    ...
    <xsl:apply-templates select="dagboek/entry" />
</xsl:template>

Basics like these are an absolute requirement to get anything done in Symphony.

I've only recently rediscovered Allen's apply-templates Tutorial, maybe it will help you understand. I urge you to search some additional documentation yourself it this doesn't help though.

It works now with one problem. When I have the frontpage everything looks good. When I go to let's say March 2005 then the recent-posts get messed up. I looks like this piece get executed:

<xsl:template match="entry">
    <h3> 
    <xsl:value-of select="titel" /> 
  </h3>
  <div class="post-inner">
     <div class="date-tab">
         <span class="month">
               <xsl:call-template name="format-date">
               <xsl:with-param name="date" select="datum"/>
            <xsl:with-param name="format" select="'M'"/>
               </xsl:call-template>
         </span>
         <span class="day">
                <xsl:call-template name="format-date">
            <xsl:with-param name="date" select="datum"/>
            <xsl:with-param name="format" select="'d'"/>
                </xsl:call-template>
         </span>
   </div>
        <xsl:apply-templates select="tekst" />
   </div>
</xsl:template>

instead of this piece of xslt:

<xsl:template match="recent-posts/entry">
<ul>
<li>
<xsl:call-template name="format-date">
 <xsl:with-param name="date" select="datum"/>
 <xsl:with-param name="format" select="'x M Y'"/>
</xsl:call-template> <br />
<xsl:value-of select="titel" /> <br /> <br />
</li>
</ul>
</xsl:template>

So now looking how to solve this one. If someone has a tip I be very happy.

That's probably a priorities problem and really depends on what other XSLT code you have. Can you create a gist or pastie with all .xsl files (page and utilities) that are being used in this example?

Here's a pastie: http://pastebin.com/Br3ejudG

Yes, it has to do with priorities: The overly zealous template matches any entry, not just the daegbook/entry one. Even tough the recent-posts/entry expression is more precise and thusly has a higher priority, its priority is being lowered by the <xsl:import /> structure.

Every template in a stylesheet that has been imported have a lower priority than the ones in the file doing the import. Every template in a stylesheet that has been imported into a stylesheet that in turn has been imported have an even lower priority and so forth.

An easy fix would be to make the overriding expression more precise: dagboek/entry instead of just entry.

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details