We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
  • Hello, i’m having some bother figuring out how to set this snippet up, what files are needed.

    I downloaded the following

    FPDI-1.2.zip
    FPDF_TPL-1.1.1.zip
    fpdf153.zip
    and your Page.pdf which was linked in your first post.

    I created a folder /assets/snippets/makepdf

    I upped all the files in the above zip archives to the makepdf/class folder and placed the Page.pdf file in the makepdf folder.

    Edited the FPDF_TPL - Version 1.1.1 file as directed in you 2nd post.


    <?php
    //
    //  FPDF_TPL - Version 1.1.1
    //
    //    Copyright 2004-2007 Setasign - Jan Slabon
    //
    //  Licensed under the Apache License, Version 2.0 (the "License");
    //  you may not use this file except in compliance with the License.
    //  You may obtain a copy of the License at
    //
    //      http://www.apache.org/licenses/LICENSE-2.0
    //
    //  Unless required by applicable law or agreed to in writing, software
    //  distributed under the License is distributed on an "AS IS" BASIS,
    //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //  See the License for the specific language governing permissions and
    //  limitations under the License.
    //
    
    require_once("fpdf.php");
    
    class FPDF_TPL extends FPDF {
      /**
         * Current SET Template-ID
         * @var int
         */
        var $curtpl = 0;
        /**
         * Array of Tpl-Data
         * @var array
         */
        var $tpls = array();
    
        /**
         * Current Template-ID
         * @var int
         */
        var $tpl = 0;
        
        /**
         * "In Template"-Flag
         * @var boolean
         */
        var $_intpl = false;
        
        /**
         * Nameprefix of Templates used in Resources-Dictonary
         * @var string A String defining the Prefix used as Template-Object-Names. Have to beginn with an /
         */
        var $tplprefix = "/TPL";
    
        /**
         * Resources used By Templates and Pages
         * @var array
         */
        var $_res = array();
        
        /**
         * Constructor
         * See FPDF-Documentation
         * @param string $orientation
         * @param string $unit
         * @param mixed $format
         */
        function fpdf_tpl($orientation='P',$unit='mm',$format='A4') {
            parent::fpdf($orientation,$unit,$format);
        }
        
        /**
         * Start a Template
         *
         * This method starts a template. You can give own coordinates to build an own sized
         * Template. Pay attention, that the margins are adapted to the new templatesize.
         * If you want to write outside the template, for example to build a clipped Template,
         * you have to set the Margins and "Cursor"-Position manual after beginTemplate-Call.
         *
         * If no parameter is given, the template uses the current page-size.
         * The Method returns an ID of the current Template. This ID is used later for using this template.
         * Warning: A created Template is used in PDF at all events. Still if you don't use it after creation!
         *
         * @param int $x The x-coordinate given in user-unit
         * @param int $y The y-coordinate given in user-unit
         * @param int $w The width given in user-unit
         * @param int $h The height given in user-unit
         * @return int The ID of new created Template
         */
        function beginTemplate($x=null,$y=null,$w=null,$h=null) {
            if ($this->page <= 0)
                $this->error("You have to add a page to fpdf first!");
    
            if ($x == null)
                $x = 0;
            if ($y == null)
                $y = 0;
            if ($w == null)
                $w = $this->w;
            if ($h == null)
                $h = $this->h;
    
            // Save settings
            $this->tpl++;
            $tpl =& $this->tpls[$this->tpl];
            $tpl = array(
                'o_x' => $this->x,
                'o_y' => $this->y,
                'o_AutoPageBreak' => $this->AutoPageBreak,
                'o_bMargin' => $this->bMargin,
                'o_tMargin' => $this->tMargin,
                'o_lMargin' => $this->lMargin,
                'o_rMargin' => $this->rMargin,
                'o_h' => $this->h,
                'o_w' => $this->w,
                'buffer' => '',
                'x' => $x,
                'y' => $y,
                'w' => $w,
                'h' => $h
            );
    
            $this->SetAutoPageBreak(false);
            
            // Define own high and width to calculate possitions correct
            $this->h = $h;
            $this->w = $w;
    
            $this->_intpl = true;
            $this->SetXY($x+$this->lMargin,$y+$this->tMargin);
            $this->SetRightMargin($this->w-$w+$this->rMargin);
    
            return $this->tpl;
        }
        
        /**
         * End Template
         *
         * This method ends a template and reset initiated variables on beginTemplate.
         *
         * @return mixed If a template is opened, the ID is returned. If not a false is returned.
         */
        function endTemplate() {
            if ($this->_intpl) {
                $this->_intpl = false; 
                $tpl =& $this->tpls[$this->tpl];
                $this->SetXY($tpl['o_x'], $tpl['o_y']);
                $this->tMargin = $tpl['o_tMargin'];
                $this->lMargin = $tpl['o_lMargin'];
                $this->rMargin = $tpl['o_rMargin'];
                $this->h = $tpl['o_h'];
                $this->w = $tpl['o_w'];
                $this->SetAutoPageBreak($tpl['o_AutoPageBreak'], $tpl['o_bMargin']);
                
                return $this->tpl;
            } else {
                return false;
            }
        }
        
        /**
         * Use a Template in current Page or other Template
         *
         * You can use a template in a page or in another template.
         * You can give the used template a new size like you use the Image()-method.
         * All parameters are optional. The width or height is calculated automaticaly
         * if one is given. If no parameter is given the origin size as defined in
         * beginTemplate() is used.
         * The calculated or used width and height are returned as an array.
         *
         * @param int $tplidx A valid template-Id
         * @param int $_x The x-position
         * @param int $_y The y-position
         * @param int $_w The new width of the template
         * @param int $_h The new height of the template
         * @retrun array The height and width of the template
         */
        function useTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0) {
            if ($this->page <= 0)
                $this->error("You have to add a page to fpdf first!");
    
            if (!isset($this->tpls[$tplidx]))
                $this->error("Template does not exist!");
                
            if ($this->_intpl) {
                $this->_res['tpl'][$this->tpl]['tpls'][$tplidx] =& $this->tpls[$tplidx];
            }
              /**
         * setTemplate makes sure new pages always have the template.
         */
        function setTemplate($tplidx=null) {
        	//If the template ID is set and exists.
        	if (isset($this->tpls[$tplidx]) ) {
        		$this->curtpl = $tplidx;
        	} else {
        		$this->curtpl = 0;
        	}
    	}
            $tpl =& $this->tpls[$tplidx];
            $x = $tpl['x'];
            $y = $tpl['y'];
            $w = $tpl['w'];
            $h = $tpl['h'];
            
            if ($_x == null)
                $_x = $x;
            if ($_y == null)
                $_y = $y;
            $wh = $this->getTemplateSize($tplidx,$_w,$_h);
            $_w = $wh['w'];
            $_h = $wh['h'];
        
            $this->_out(sprintf("q %.4f 0 0 %.4f %.2f %.2f cm", ($_w/$w), ($_h/$h), $_x*$this->k, ($this->h-($_y+$_h))*$this->k)); // Translate 
            $this->_out($this->tplprefix.$tplidx." Do Q");
    
            return array("w" => $_w, "h" => $_h);
        }
        
        /**
         * Get The calculated Size of a Template
         *
         * If one size is given, this method calculates the other one.
         *
         * @param int $tplidx A valid template-Id
         * @param int $_w The width of the template
         * @param int $_h The height of the template
         * @return array The height and width of the template
         */
        function getTemplateSize($tplidx, $_w=0, $_h=0) {
            if (!$this->tpls[$tplidx])
                return false;
    
            $tpl =& $this->tpls[$tplidx];
            $w = $tpl['w'];
            $h = $tpl['h'];
            
            if ($_w == 0 and $_h == 0) {
                $_w = $w;
                $_h = $h;
            }
    
        	if($_w==0)
        		$_w=$_h*$w/$h;
        	if($_h==0)
        		$_h=$_w*$h/$w;
        		
            return array("w" => $_w, "h" => $_h);
        }
        
        /**
         * See FPDF-Documentation ;-)
         */
        function SetFont($family,$style='',$size=0) {
            /**
             * force the resetting of font changes in a template
             */
            if ($this->_intpl)
                $this->FontFamily = '';
                
            parent::SetFont($family, $style, $size);
           
            $fontkey = $this->FontFamily.$this->FontStyle;
            
            if ($this->_intpl) {
                $this->_res['tpl'][$this->tpl]['fonts'][$fontkey] =& $this->fonts[$fontkey];
            } else {
                $this->_res['page'][$this->page]['fonts'][$fontkey] =& $this->fonts[$fontkey];
            }
        }
        
        /**
         * See FPDF-Documentation ;-)
         */
        function Image($file,$x,$y,$w=0,$h=0,$type='',$link='') {
            parent::Image($file,$x,$y,$w,$h,$type,$link);
            if ($this->_intpl) {
                $this->_res['tpl'][$this->tpl]['images'][$file] =& $this->images[$file];
            } else {
                $this->_res['page'][$this->page]['images'][$file] =& $this->images[$file];
            }
        }
        
    
     /**
         * See FPDF-Documentation ;-)
         *
         * AddPage is not available when you're "in" a template.
         */
        function AddPage($orientation='') {
            if ($this->_intpl)
                $this->Error('Adding pages in templates isn\'t possible!');
            parent::AddPage($orientation);
            //Apply the current template before any text is applied.
            if (!empty($this->curtpl)) {
            	$this->UseTemplate($this->curtpl);
            }
        }
    
        /**
         * Preserve adding Links in Templates ...won't work
         */
        function Link($x,$y,$w,$h,$link) {
            if ($this->_intpl)
                $this->Error('Using links in templates aren\'t possible!');
            parent::Link($x,$y,$w,$h,$link);
        }
        
        function AddLink() {
            if ($this->_intpl)
                $this->Error('Adding links in templates aren\'t possible!');
            return parent::AddLink();
        }
        
        function SetLink($link,$y=0,$page=-1) {
            if ($this->_intpl)
                $this->Error('Setting links in templates aren\'t possible!');
            parent::SetLink($link,$y,$page);
        }
        
        /**
         * Private Method that writes the form xobjects
         */
        function _putformxobjects() {
            $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
    	    reset($this->tpls);
            foreach($this->tpls AS $tplidx => $tpl) {
    
                $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer'];
        		$this->_newobj();
        		$this->tpls[$tplidx]['n'] = $this->n;
        		$this->_out('<<'.$filter.'/Type /XObject');
                $this->_out('/Subtype /Form');
                $this->_out('/FormType 1');
                $this->_out(sprintf('/BBox [%.2f %.2f %.2f %.2f]',$tpl['x']*$this->k, ($tpl['h']-$tpl['y'])*$this->k, $tpl['w']*$this->k, ($tpl['h']-$tpl['y']-$tpl['h'])*$this->k));
                $this->_out('/Resources ');
    
                $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
            	if (isset($this->_res['tpl'][$tplidx]['fonts']) && count($this->_res['tpl'][$tplidx]['fonts'])) {
                	$this->_out('/Font <<');
                    foreach($this->_res['tpl'][$tplidx]['fonts'] as $font)
                		$this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
                	$this->_out('>>');
                }
            	if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) || 
            	   isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls']))
            	{
                    $this->_out('/XObject <<');
                    if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) {
                        foreach($this->_res['tpl'][$tplidx]['images'] as $image)
                  			$this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
                    }
                    if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) {
                        foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $tpl)
                            $this->_out($this->tplprefix.$i.' '.$tpl['n'].' 0 R');
                    }
                    $this->_out('>>');
            	}
            	$this->_out('>>');
            	
            	$this->_out('/Length '.strlen($p).' >>');
        		$this->_putstream($p);
        		$this->_out('endobj');
            }
        }
        
        /**
         * Private Method
         */
        function _putresources() {
            $this->_putfonts();
        	$this->_putimages();
        	$this->_putformxobjects();
            //Resource dictionary
        	$this->offsets[2]=strlen($this->buffer);
        	$this->_out('2 0 obj');
        	$this->_out('<<');
        	$this->_putresourcedict();
        	$this->_out('>>');
        	$this->_out('endobj');
        }
        
        function _putxobjectdict() {
            parent::_putxobjectdict();
            
            if (count($this->tpls)) {
                foreach($this->tpls as $tplidx => $tpl) {
                    $this->_out($this->tplprefix.$tplidx.' '.$tpl['n'].' 0 R');
                }
            }
        }
    
        /**
         * Private Method
         */
        function _out($s) {
    	   //Add a line to the document
    	   if ($this->state==2) {
               if (!$this->_intpl)
    	           $this->pages[$this->page].=$s."\n";
               else
                   $this->tpls[$this->tpl]['buffer'] .= $s."\n";
           } else {
    		   $this->buffer.=$s."\n";
           }
        }
    }
    
    ?>


    I set the parent to 16 in the snippet call
    [!MakePDF? &parent=`16` &title=`terms` &author=`rossco` !]

    and I get the error below
    FPDF error: Unable to find xref table - Maybe a Problem with ’auto_detect_line_endings’


    Could i get a dummy guide to setting this up? Thanks


      Ross Sivills - MD AugmentBLU Edinburgh, Scotland UK
      AugmentBLU - MODX Partner

      BLUcart - MODX Revolution E-Commerce & Shopping Cart
      • 21560
      • 145 Posts
      You might have to look at FDPF itself as I’ve never seen that error before.

      Also, I’m trying to fix my own snippet to allow for multiple parents as my own situation has changed. Also: I’m making support for all kinds of stuff. ^_^

      I’ve modified the original post with the latest update and the modified library. This should make it a lot easier for new people.
        [font=Times]Comics, stories, music, graphics, games and more! http://Nimja.com
        • 8960
        • 150 Posts
        I was trying to view your site to get an idea of what exactly your snippet does and how I might be able to use it. I followed the link to your site and tried to click on the PDF icon on the right, but in Firefox on the Mac, I can’t because the chapter links stretch all the way across and block your right side links.

        I’m including a screenshot so you might get an idea of what I’m talking about.
          • 21560
          • 145 Posts
          Interesting ’bug’ I haven’t encountered this in any other browser.

          But It should be fixed now.

          Could you be a dear and check it in Safari?
            [font=Times]Comics, stories, music, graphics, games and more! http://Nimja.com
            • 8960
            • 150 Posts
            Done & done. Everything looks good.

            Nice design, BTW. I like the background image.
              • 21560
              • 145 Posts
              Thank you, it’s just one of this little things that make the design more fun. Of course I create everything myself, even if it’s loosely based on another design.

              I’ve found MODx to be very nicely usable for any design style, really.

              Aaaanyway. I wonder if there are any people having problems or use of my PDF functionality?
                [font=Times]Comics, stories, music, graphics, games and more! http://Nimja.com
              • How do I create PDF templates with images? I did create one but the snippet doesn’t pick up the image in the document... thanks
                  Ross Sivills - MD AugmentBLU Edinburgh, Scotland UK
                  AugmentBLU - MODX Partner

                  BLUcart - MODX Revolution E-Commerce & Shopping Cart
                  • 21560
                  • 145 Posts
                  Well, you have to make a single-page PDF document that’s used as the template.

                  Any images, text, vector-shapes or whatever in that first page are picked up and used in the rest of the document.

                  On the website I use a watermark-like shape of my logo on the background, so I know this works. I haven’t explicitdly tried to use normal images (JPG/GIF/PNG/etc.) but it should pose no problem.
                    [font=Times]Comics, stories, music, graphics, games and more! http://Nimja.com
                  • I’ve tried inserting an image and setting one as the background and both times the image doesn’t appear. If I manually access the file it’s there but when using the snippet the image is gone? I’ll keep trying. Great work on this snippet.
                      Ross Sivills - MD AugmentBLU Edinburgh, Scotland UK
                      AugmentBLU - MODX Partner

                      BLUcart - MODX Revolution E-Commerce & Shopping Cart
                      • 21560
                      • 145 Posts
                      The image is inside a PDF?

                      And thanks, I’ve still got plenty ideas. Especially to see if I can make a sort of Wiki-format support (because I like the ease of the wiki-format)
                        [font=Times]Comics, stories, music, graphics, games and more! http://Nimja.com