We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 23506
    • 156 Posts
    Mark, help...
      • 5628
      • 44 Posts
      Howdy Pardners
      Trying to use the splitPagination snippet for a Ditto call to pull news articles out of their parent folder (in this case container `77`) in groups of 4.
      My Ditto call is as follows. Pulls the articles out fine but doesn’t create a pagination. What am I missing?
      [!Ditto? &parents=`77` &depth=`1` &hideFolders=`1` &sortBy=`pub_date` &display=`4` &paginate=`1` &paginateAlwaysShowLinks=`1`!]
      
      [!splitPagination &return=`1`!] 


      ModX version 0.9.6
      Ditto version 2.0.2

      Cole
        • 2912
        • 315 Posts
        Hi All,

        I’m having trouble getting the right output for my pages.

        I have 14 pages in my list and the snippet appears to be working but the pages are shown in full 1, 2, 3, 4 etc all the way to 14. It just won’t create the ’...’ in between page 3 and 12.

        Is there something I’m doing wrong?

        <div align="center"><em>Total Movies in Database/Section: <strong>[+total+]</strong></em><br/>
        Pages: <br/></div>
        <br/>
        <div id="nl_pages" align="center"><!--[+previous+] [+next+]--> [+splitPages+]</div>
        <h5>Section: [+tags+]</h5>
        <hr/>
        [!Ditto? &startID=`[*id*]` &display=`5` &commentsChunk=`MovieComments` &tpl=`DBDittoSummary` &paginate=`1` &alwaysshow=`1` &sortBy=`pagetitle` &sortDir=`asc` &tagData=`MovieCategory,MovieCreator,MovieGameEngine,MovieProductionDate` &tagDelimiter=`,`!][!SplitPagination?!]
        
          BBloke
          • 4749
          • 623 Posts
          Has anyone got this to work? I’m getting results like this:
          1, 1.0666667, 2.0666667, 3.0666667, 4.0666667, 5.0666667, 6.0666667, 7.0666667, 8.0666667, 9.0666667, 10.0666667, 11.0666667, 12.0666667...38, 39,40
          


          I’ve tried cached, uncached, [!splitPagination? &return=`1`!], [!splitPagination!]. I’ve looked through a few different threads and still cannot find a solution to this. Thanks for any insight.
            The MODx has you...
            Utah Web Design
            • 2912
            • 315 Posts
            Please find below revised code that should/will help with the decimal point problem as above.

            I hope it works for all.

            <?php
            // Snippet: splitPagination
            // Must be placed immediately following a Ditto call
            // Based on the function written by Aaron Hall, evilwalrus.org
            if (!function_exists("generatePagination")) {
            function generatePagination($curPage, $totResults, $resultsPerPage)
            {
            	$totPages = ceil($totResults / $resultsPerPage);
            	
            	$pagesBefore = $curPage - 1;
            	$pagesAfter = $totPages - $curPage;
            	
            	$tabArr = array();
            	
            	if($totPages > 15) {
            		
            		if($pagesBefore > 7) {
            			$tabArr = array(1,2,0);
            			
            			if($pagesAfter > 7)
            			{
            				for($i=($curPage-(4)); $i<$curPage; $i++) { $tabArr[] = $i; }
            			} else {
            				for($i=($totPages-11); $i<$curPage; $i++) { $tabArr[] = $i; }
            			}
            		} else {
            			for($i=1; $i<$curPage; $i++) { $tabArr[] = $i; }
            		}
            		
            		$tabArr[] = $curPage;
            		
            		if($pagesAfter > 7) {
            			if($pagesBefore > 7) {				
            				for($i=($curPage+1); $i<=$curPage+4; $i++) { $tabArr[] = $i; }
            			} else {
            				for($i=($curPage+1); $i<13; $i++) { $tabArr[] = $i; }
            			}
            			$tabArr[] = 0;
            			$tabArr[] = $totPages-1;
            			$tabArr[] = $totPages;
            		} else {
            			for($i=($curPage+1); $i<=$totPages; $i++) { $tabArr[] = $i; }
            		}
            		
            	} else {
            		for($i=1;$i<=$totPages;$i++) { $tabArr[] = $i; }
            	}
            			
            	return $tabArr;
            	
            }
            }
            $id = isset($id) ? $id.'_' : '';
            $total = isset($total) ? $total : $modx->getPlaceholder($id."total");
            $start = isset($start) ? $start : $modx->getPlaceholder($id."start");
            $display = isset($display) ? $display : $modx->getPlaceholder($id."perPage");
            $currentPage = isset($currentPage) ? $currentPage : $modx->getPlaceholder($id."current");
            $landing = isset($tagDocumentID) ? $tagDocumentID : $modx->documentObject['id'];
            if ($total == 0 || $display==0) {
            	return false;
            }
            $page = ceil($start/$display);
            $return = isset($return) ? $return : 0;
            $paginationArray = generatePagination($page, $total, $display);
            $ph = "";
            $cInc = $_GET[$id.'start'];
            foreach($paginationArray as $page) {
            	$inc = ($page-1)*$display;
            	if($page == 0) {
            		$ph .= "..."; // print an elipse, representing pages that aren't displayed
            	} else if ($inc==$cInc) {
            		$ph .= "<span class=\"ditto_currentpage\">$page</span>";		
            	} else {
            		$ph .= "<a class=\"ditto_page\" href='".ditto::buildURL("start=".$inc,$landing,$id)."'>$page</a>";
            	}
            	
            
            }
            $modx->setPlaceholder($id."splitPages",$ph);
            if ($return) return $ph;
            ?>
            
              BBloke
              • 4749
              • 623 Posts
              Thanks BBloke! Worked great for me and saved me a lot of time. laugh
                The MODx has you...
                Utah Web Design
                • 21056
                • 327 Posts
                I’ve refactored this code almost completely - it now has fully configurable options (previously it was fixed at 15 pages visible, 2 at either end before ellipses) and made it fully templatable. By default, useful classes are applied for styling (e.g. current, first, last, and index number) I’ve included documentation of all the options.

                Please try it out and let me know any bugs before I upload to the repository.

                See also attached image of some examples.

                <?php
                /**
                 * splitPagination
                 *
                 * Create split pagination for large Ditto result sets
                 * 
                 * @category	snippet
                 * @version 	2.0
                 * @license 	http://www.gnu.org/copyleft/gpl.html GNU Public License (GPL)
                 * @internal	@properties 
                 * @internal	@modx_category Navigation
                 * @author		Nick Crossland - rckt.co.uk. Based on the function written by Aaron Hall, evilwalrus.org.
                 */
                 
                
                /* 
                
                PURPOSE
                When a Ditto result set is large, the pagination can grow too large to fit comfortably and usably on the page. 
                This snippet provides alternative "Google" style pagination, where a maximum number of pages are shown - the 
                first and last pages of the results, and the pages immediately surrounding the current page.
                 e.g. instead Ditto's default pagination output of
                
                [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [*11*] [12] [13] [14] [15] [16] [17] [18] [19] [20]
                
                (current page is 11) this snippet produces
                
                [1] [2] ... [8] [9] [10] [*11*] [12] [13] [14] ... [19] [20]
                
                
                REQUIREMENTS
                This snippet is tested with Ditto 2.1 in ModX Evo 1.0.x
                
                
                INSTALLATION
                Create a new snippet named splitPagination, and paste the contents of this file into it. 
                
                
                USAGE
                Place the snippet immediately following a Ditto call. 
                
                e.g. 1 
                
                [[splitPagination]]
                will just create a placeholder named "splitPages" - to insert into the correct place of your document use [+splitPages+]
                
                e.g.2
                [[splitPagination? &id=`myDitto` &pagesToShow=`10` &constantEndCount=`3` &ellipses=`myChunk` &return=`1`]]
                will output the pagination directly, using data obtained from the Ditto call with the ID of "myDitto". 
                It will display a maximum of 10 links to pages, with three before/after the ellipses at the beginning and end. 
                The HTML to use for the ellipses will be obtained from the "myChunk" chunk.
                
                
                PARAMETERS
                
                 Param: id
                
                    Purpose:
                    If there is more than one Ditto call on a page, or your Ditto call has the ID paramater set, this is required to 
                	know which Ditto ID to use.
                
                    Options:
                    Ditto ID parameter
                	
                	Default:
                    <none>
                	
                	
                	
                 Param: pagesToShow
                
                    Purpose:
                    Maximum number of page links to show. Any pages above this number will be replaced by ellipses. 
                	Sets of ellipses are included in this count, to ensure the total size of the pagination remains largely 
                	the same regardless of current position.
                
                    Options:
                    Number
                	
                	Default:
                    15	
                	
                
                
                 Param: constantEndCount
                
                    Purpose:
                    Number of pages links to display at the beginning and end of the results set, before and after the ellipses
                	e.g. set to 2, the results would display:	
                	[1] [2] ... [99] [100]
                	
                	or set to 4, the results would display:
                	[1] [2] [3] [4] ... [97] [98] [99] [100]	
                
                    Options:
                    Number
                	
                	Default:
                    2	
                	
                	
                 Param: return
                
                    Purpose:
                    Output the pagination directly from the location of the snippet, rather than to a placeholder
                
                    Options:
                    Boolean
                	
                	Default:
                    0	
                
                
                	
                 Param: tplEllipses
                
                    Purpose:
                    Chunk name, or HTML that should be used to indicate a break in the page numbering. ModX doesn't work very
                	well (as of 1.0.x) with = sign within parameters, so if you wish to use HTML containing = sign, it is 
                	suggested to put it in a chunk rather than supply HTML directly.
                
                    Options:
                    Chunk name or HTML
                	
                	Default:
                    <span class="splitPagination">...</span>	
                	
                
                 Param: tplCurrent
                
                    Purpose:
                    Chunk name, or HTML that should be used for the current results page. ModX doesn't work very
                	well (as of 1.0.x) with = sign within parameters, so if you wish to use HTML containing = sign, it is 
                	suggested to put it in a chunk rather than supply HTML directly.
                	
                	The [+page+] placeholder will be replaced by the page number
                	The [+class+] placeholder will be replace by a class representing first or last items if this applies (see firstClass and lastClass params)
                
                    Options:
                    Chunk name or HTML
                	
                	Default:
                    <span class="ditto_currentpage ditto_page_[+page+][+class+]">[+page+]</span>		
                	
                	
                
                 Param: tplPageLink
                
                    Purpose:
                    Chunk name, or HTML that should be used for links to all results page (other than current). ModX doesn't work very
                	well (as of 1.0.x) with = sign within parameters, so if you wish to use HTML containing = sign, it is 
                	suggested to put it in a chunk rather than supply HTML directly.
                	
                	The [+page+] placeholder will be replaced by the page number
                	The [+url+] placeholder will be replaced by the link URL
                	The [+class+] placeholder will be replace by a class representing first or last items if this applies (see firstClass and lastClass params)
                
                    Options:
                    Chunk name or HTML
                	
                	Default:
                    <a class="ditto_page ditto_page_[+page+][+class+]" href="[+url+]">[+page+]</a>
                
                
                
                 Param: firstClass
                
                    Purpose:
                    Class applied to the first page link
                	
                    Options:
                    HTML class
                	
                	Default:
                    first
                
                
                
                 Param: lastClass
                
                    Purpose:
                    Class applied to the last page link
                	
                    Options:
                    HTML class
                	
                	Default:
                    last
                	
                
                ---------------------------------------------------------------------------------------
                The following parameters are available as manual overrides, however they are normally 
                populated with correct values automatically.
                	
                	
                 Param: total
                
                    Purpose:
                   	Total number of results from the Ditto query - usually obtained automatically from Ditto. Setting manually may have
                	unpredictable results!
                
                    Options:
                    Number
                	
                	Default:
                    From Ditto results	
                	
                	
                	
                 Param: start
                
                    Purpose:
                   	Start position of results from the Ditto query - usually obtained automatically from Ditto. Setting manually may have
                	unpredictable results!
                
                    Options:
                    Number
                	
                	Default:
                    From Ditto results		
                	
                	
                	
                 Param: display
                
                    Purpose:
                   	Number of results per page to display - usually obtained automatically from Ditto. Setting manually may have
                	unpredictable results!
                
                    Options:
                    Number
                	
                	Default:
                    From Ditto results	
                	
                	
                	
                 Param: currentPage
                
                    Purpose:
                   	Override current page. Usually automatically calculated. Setting manually may have
                	unpredictable results!
                
                    Options:
                    Number
                	
                	Default:
                    From URL	
                
                
                	
                 Param: landing
                
                    Purpose:
                   	Landing page for pagination links. 
                
                    Options:
                    Document ID
                	
                	Default:
                    Current page
                	
                	
                
                
                 
                
                
                */
                
                
                
                if (!function_exists("generatePagination")) {
                	
                function generatePagination($currentPage, $totalResults, $resultsPerPage, $pagesToShow, $constantEndCount) {
                	
                	// How many pages are there altogether?
                	$totalPages = ceil($totalResults / $resultsPerPage);
                	
                	// How far through are we?
                	$pagesBefore = $currentPage - 1;
                	$pagesAfter = $totalPages - $currentPage;
                	
                	// An array of tabs to display (made up of page numbers)
                	$tabArr = array();
                	
                	// If we need to split the pagination
                	if($totalPages > $pagesToShow) {
                		
                		// If we're currently more than half way through
                		if($pagesBefore > $pagesToShow/2) {
                			
                			// Always show pages 1 and 2 (or whatever the constant end count is), then a separator
                			for($i=1; $i<=$constantEndCount; $i++) { $tabArr[] = $i; }
                			$tabArr[] = 0;
                				
                			// If the number of pages after the current page is more than the number of available slots
                			if($pagesAfter >= $pagesToShow/2) {
                				$empty_slots_before = floor( ($pagesToShow - ($constantEndCount*2 /*there are two ends*/) - 1 /*the current page*/) / 2 /*only half*/) -1  /*the set of dots counts as one slot*/;
                			} else {
                				$empty_slots_before = $pagesToShow - count($tabArr) - 1 /*current page*/ - $pagesAfter /*How many after*/;
                			}
                			
                			// Insert the tabs	
                			for($i=($currentPage-$empty_slots_before); $i<$currentPage; $i++) { $tabArr[] = $i; }	
                			
                		} else {
                			for($i=1; $i<$currentPage; $i++) { $tabArr[] = $i; }
                		}
                		
                		// Insert current page
                		$tabArr[] = $currentPage;		
                		
                		// If we're less than half way through
                		if($pagesAfter > $pagesToShow/2) {
                			
                			// How many more slots do we want to show after the current page?
                			$empty_slots_after = $pagesToShow - count($tabArr) - $constantEndCount - 1/*the set of dots*/;
                			
                			// Insert the tabs	
                			for($i=($currentPage+1); $i<=$currentPage+$empty_slots_after; $i++) { $tabArr[] = $i; }
                			
                			// Add a separator
                			$tabArr[] = 0;
                			
                			// Always show pages last 2 pages (or whatever the constant end count is)
                			for($i=$totalPages-$constantEndCount+1; $i<=$totalPages; $i++) { $tabArr[] = $i; }
                
                		} else {
                			for($i=($currentPage+1); $i<=$totalPages; $i++) { $tabArr[] = $i; }
                		}
                		
                	} else { // No need to split the pagination
                		for($i=1;$i<=$totalPages;$i++) { $tabArr[] = $i; }
                	}
                			
                	return $tabArr;
                	
                	} // end function
                } // end if
                
                
                
                
                // ----------------------------------------------------------------------------------------------------------------
                
                
                
                
                
                
                
                // Define some paramaters
                $id = isset($id) ? $id.'_' : '';
                $total = isset($total) ? $total : $modx->getPlaceholder($id."total");
                $start = isset($start) ? $start : $modx->getPlaceholder($id."start");
                $display = isset($display) ? $display : $modx->getPlaceholder($id."perPage");
                $currentPage = isset($currentPage) ? $currentPage : $modx->getPlaceholder($id."current");
                $landing = isset($tagDocumentID) ? $tagDocumentID : $modx->documentObject['id'];
                
                $pagesToShow = isset($pagesToShow) && is_numeric($pagesToShow) ? $pagesToShow : 15;
                $constantEndCount = isset($constantEndCount) && is_numeric($constantEndCount) ? $constantEndCount : 2;
                
                
                $tplEllipses = isset($tplEllipses) ? $modx->getChunk($tplEllipses) : '';
                $tplEllipses = !empty($tplEllipses) ? $tplEllipses : '<span class="splitPagination">...</span>';
                
                $tplCurrent = isset($tplCurrent) ? $modx->getChunk($tplCurrent) : '';
                $tplCurrent = !empty($tplCurrent) ? $tplCurrent : '<span class="ditto_currentpage ditto_page_[+page+][+class+]">[+page+]</span>';
                
                $tplPageLink = isset($tplPageLink) ? $modx->getChunk($tplPageLink) : '';
                $tplPageLink = !empty($tplPageLink) ? $tplPageLink : '<a class="ditto_page ditto_page_[+page+][+class+]" href="[+url+]">[+page+]</a>';
                
                $firstClass = isset($firstClass) ? $firstClass: 'first';
                $lastClass = isset($lastClass) ? $lastClass: 'last';
                
                
                $return = isset($return) ? $return : 0;
                
                // Do nothing if there's nothing to do
                if ($total == 0 || $display==0) {
                	return false;
                }
                
                // What page are we on?
                $page = ceil($start/$display);
                
                // Generate the pagination
                $paginationArray = generatePagination($page, $total, $display, $pagesToShow, $constantEndCount);
                
                // Create empty placeholder for output
                $ph = "";
                
                // Build the output
                foreach($paginationArray as $page) {
                	$inc = ($page-1)*$display;
                	
                	// First or last classes
                	if ($page == 1) { 
                			$newClass = ' ' . $firstClass;
                	} else if ($page == ceil($total/$display)) {
                		$newClass = ' ' . $lastClass;
                	} else {
                		$newClass = '';
                	}
                	
                	// Insert into output
                	if($page == 0) {
                		$ph .= $tplEllipses; // print an elipse, representing pages that aren't displayed
                	} else if ($inc==$_GET[$id.'start']) {
                		$newLink = str_replace('[+class+]', $newClass , $tplCurrent);
                		$ph .= str_replace('[+page+]', $page, $newLink);	
                	} else {
                		$newLink = str_replace('[+url+]', ditto::buildURL("start=".$inc,$landing,$id) , $tplPageLink);		
                		$newLink = str_replace('[+class+]', $newClass , $newLink);
                		$ph .= str_replace('[+page+]', $page, $newLink);	
                	}
                }
                
                // Set the placeholder
                $modx->setPlaceholder($id."splitPages",$ph);
                
                // Or return the output
                if ($return) return $ph;
                
                
                
                ?>
                  Author: ManagerManager plugin - customise your ModX manager interface

                  Rckt - web development, Sheffield, UK
                  • 26931
                  • 2,314 Posts
                  I’ve refactored this code almost completely
                  oh, nice smiley thanks ncrossland
                    • 29802
                    • 36 Posts
                    Thank you for this, it works for me.

                    Two questions if I may:

                    1) Is it possible to output a total-pages count? Eg: "Showing x out of x pages".

                    [[Ditto? &parents=`2` &start=`0` &display=`15` &id=`pagenext` &paginate=`1` &tplFirst=`firstpost` &tpl=`summaryBlog` &tplAlt=`summaryBlog_alt` &paginateAlwaysShowLinks=`0` &tplPaginatePage=`paginatePage` &tplPaginateNext=`paginatePageNext` &tplPaginatePrevious=`paginatePagePrev`]]
                    
                    [[splitPagination? &id=`pagenext` &pagesToShow=`15` &constantEndCount=`3` &ellipses=`paginatePage` &return=`1`]]
                    
                    <p>Showing <strong>[+start+]</strong> - <strong>[+stop+]</strong> of <strong>[+total+]</strong> blog posts</p>
                    
                    <div id="nl_pages">
                    [+previous+] [+pages+] [+next+]
                    </div>
                    
                    [+splitPagination+]
                    


                    2) When assigning an id="pagenext", as above, to the ditto call, splitPagination appends it to URLs with an underscore (blog?pagenext_start=330). Is there a way to prevent this (or have I missed it)?

                    I’m hoping to employ your snippet on an existing website, meaning the search engines already have the "old" ditto URL format (blog?start=330).

                    Finally, for feedback purposes, it would be great if it could output "Next" and "Prev" links (or again, am I missing something).

                    Thanks again.
                      • 21056
                      • 327 Posts
                      Quote from: TheWhippinpost at Dec 14, 2009, 12:54 PM


                      1) Is it possible to output a total-pages count? Eg: "Showing x out of x pages".


                      The previous and next links are generated by Ditto, not this snippet - I think if you supply an ID to Ditto, you also have to prefix them to the next / prev links, e.g.

                      [+pagenext_previous+] [+pagenext_pages+] [+pagenext_next+]


                      Quote from: TheWhippinpost at Dec 14, 2009, 12:54 PM


                      When assigning an id="pagenext", as above, to the ditto call, splitPagination appends it to URLs with an underscore (blog?pagenext_start=330). Is there a way to prevent this (or have I missed it)?


                      The URL parameter is similar, and also created by Ditto (not this snippet) - it’s generated like that because of the ID. (it works &dittoid_start=330 ). This is to cater for having more than one Ditto call on the page. If there is only one ditto call, you could remove the ID, or move the ID to another Ditto call and leave this one blank.
                        Author: ManagerManager plugin - customise your ModX manager interface

                        Rckt - web development, Sheffield, UK