{"id":21420088,"url":"https://github.com/mplodowski/dynamicpdf-plugin","last_synced_at":"2025-07-14T06:31:49.172Z","repository":{"id":31816850,"uuid":"35383528","full_name":"mplodowski/dynamicpdf-plugin","owner":"mplodowski","description":"https://octobercms.com/plugin/renatio-dynamicpdf","archived":false,"fork":false,"pushed_at":"2025-07-07T19:27:45.000Z","size":1259,"stargazers_count":31,"open_issues_count":2,"forks_count":22,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-07-07T21:58:42.249Z","etag":null,"topics":["octobercms-plugin"],"latest_commit_sha":null,"homepage":"https://octobercms.com/plugin/renatio-dynamicpdf","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mplodowski.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-05-10T18:51:15.000Z","updated_at":"2025-07-07T19:27:49.000Z","dependencies_parsed_at":"2024-06-19T00:21:02.551Z","dependency_job_id":"1cbd9d3c-8291-4a2d-927e-2c82249b6c62","html_url":"https://github.com/mplodowski/dynamicpdf-plugin","commit_stats":{"total_commits":143,"total_committers":11,"mean_commits":13.0,"dds":"0.14685314685314688","last_synced_commit":"3ec918ce7cd2eb267dbeb38a47a9165e9a0f404b"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/mplodowski/dynamicpdf-plugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mplodowski%2Fdynamicpdf-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mplodowski%2Fdynamicpdf-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mplodowski%2Fdynamicpdf-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mplodowski%2Fdynamicpdf-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mplodowski","download_url":"https://codeload.github.com/mplodowski/dynamicpdf-plugin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mplodowski%2Fdynamicpdf-plugin/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264979174,"owners_count":23692453,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["octobercms-plugin"],"created_at":"2024-11-22T20:11:26.212Z","updated_at":"2025-07-14T06:31:48.787Z","avatar_url":"https://github.com/mplodowski.png","language":"PHP","funding_links":["https://www.paypal.me/mplodowski"],"categories":[],"sub_categories":[],"readme":"# Dynamic PDF Plugin\n\n**Demo URL:** https://october-demo.renatio.com/backend/backend/auth/signin\n\n**Login:** dynamicpdf\n\n**Password:** dynamicpdf\n\nThis plugin allows developers to create and edit PDF templates with a simple user interface.\n\nHTML to PDF converter uses [dompdf](https://github.com/dompdf/dompdf) library.\n\nPlugin uses dompdf wrapper for Laravel [barryvdh/laravel-dompdf](https://github.com/barryvdh/laravel-dompdf).\n\n## Like this plugin?\n\nIf you like this plugin, give this plugin a Like or Make donation with [PayPal](https://www.paypal.me/mplodowski).\n\n## My other plugins\n\nPlease check my other [plugins](https://octobercms.com/author/Renatio).\n\n## Support\n\nPlease use [GitHub Issues Page](https://github.com/mplodowski/dynamicpdf-plugin/issues) to report any issues with\nplugin.\n\n\u003e Reviews should not be used for getting support or reporting bugs, if you need support please use the Plugin support\n\u003e link.\n\nIcon made by [Darius Dan](https://www.flaticon.com/authors/darius-dan)\nfrom [www.flaticon.com](https://www.flaticon.com/).\n\n# Documentation\n\n## Installation\n\nThere are couple ways to install this plugin.\n\n1. Use `php artisan plugin:install Renatio.DynamicPDF` command.\n2. Use `composer require renatio/dynamicpdf-plugin` in project root. When you use this option you must\n   run `php artisan october:migrate` after installation.\n\n## PDF content\n\nPDF can be created in October using either PDF views or PDF templates. A PDF view is supplied by plugin in the file\nsystem in the **/views** directory. Whereas a PDF template is managed using the back-end interface via *Settings \u003e PDF \u003e\nPDF Templates*. All PDFs templates support using Twig for markup.\n\nPDF views must be registered in the Plugin registration file with the `registerPDFTemplates` and `registerPDFLayouts`\nmethod. This will automatically generate a PDF template and layout and allows them to be customized using the back-end\ninterface.\n\n## PDF layouts views\n\nPDF layouts views reside in the file system and the code used represents the path to the view file. For example PDF\nlayout with the code **author.plugin::pdf.layouts.default** would use the content in following file:\n\n```\nplugins/                 \u003c=== Plugins directory\n  author/                \u003c=== \"author\" segment\n    plugin/              \u003c=== \"plugin\" segment\n      views/             \u003c=== View directory\n        pdf/             \u003c=== \"pdf\" segment\n          layouts/       \u003c=== \"layouts\" segment\n            default.htm  \u003c=== \"default\" segment\n```\n\nThe content inside a PDF view file can include up to 3 sections: **configuration**, **CSS/LESS**, and **HTML markup**.\nSections are separated with the `==` sequence. For example:\n\n```\nname = \"Default PDF layout\"\n==\nbody {\n    font-size: 16px;\n}\n==\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003cmeta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/\u003e\n        \u003ctitle\u003eDocument\u003c/title\u003e\n        \u003cstyle type=\"text/css\" media=\"screen\"\u003e\n            {{ css|raw }}\n        \u003c/style\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n        {{ content_html|raw }}\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n\n\u003e **Note:** Basic Twig tags and expressions are supported in PDF views.\n\nThe **CSS/LESS** section is optional and a view can contain only the configuration and HTML markup sections.\n\n```\nname = \"Default PDF layout\"\n==\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003cmeta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/\u003e\n        \u003ctitle\u003eDocument\u003c/title\u003e\n        \u003cstyle type=\"text/css\" media=\"screen\"\u003e\n            {{ css|raw }}\n        \u003c/style\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n        {{ content_html|raw }}\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n\n### Configuration section\n\nThe configuration section sets the PDF view parameters. The following configuration parameters are supported:\n\n| Parameter | Description                |\n|-----------|----------------------------|\n| **name**  | the layout name, required. |\n\n### Using PDF layouts\n\nPDF layouts reside in the database and can be created by selecting *Settings \u003e PDF \u003e PDF Templates* and clicking the *\nLayouts* tab. These behave just like CMS layouts, they contain the scaffold for the PDF. PDF views and templates support\nthe use of PDF layouts. The **code** specified in the layout is a unique identifier and cannot be changed once created.\n\n## PDF templates views\n\nPDF templates reside in the file system and the code used represents the path to the view file. For example PDF template\nwith the code **author.plugin::pdf.invoice** would use the content in following file:\n\n```\nplugins/                 \u003c=== Plugins directory\n  author/                \u003c=== \"author\" segment\n    plugin/              \u003c=== \"plugin\" segment\n      views/             \u003c=== View directory\n        pdf/             \u003c=== \"pdf\" segment\n          invoice.htm    \u003c=== \"invoice\" segment\n```\n\nThe content inside a PDF view file can include up to 2 sections: **configuration** and **HTML markup**. Sections are\nseparated with the `==` sequence. For example:\n\n```\ntitle = \"Invoice\"\nlayout = \"renatio.demo::pdf.layouts.default\"\ndescription = \"Invoice template\"\nsize = \"a4\"\norientation = \"portrait\"\n==\n\u003ch1\u003eInvoice\u003c/h1\u003e\n```\n\n\u003e **Note:** Basic Twig tags and expressions are supported in PDF views.\n\n### Configuration section\n\nThe configuration section sets the PDF view parameters. The following configuration parameters are supported:\n\n| Parameter       | Description                                                   |\n|-----------------|---------------------------------------------------------------|\n| **title**       | the template title, required.                                 |\n| **layout**      | the layout code, optional.                                    |\n| **description** | the template description, optional.                           |\n| **size**        | the template paper size, optional, default `a4`.              |\n| **orientation** | the template paper orientation, optional, default `portrait`. |\n\n### Using PDF templates\n\nPDF templates reside in the database and can be created in the back-end area via *Settings \u003e PDF \u003e PDF Templates*.\nThe **code** specified in the template is a unique identifier and cannot be changed once created.\n\n\u003e **Note:** If the PDF template does not exist in the system, this code will attempt to find a PDF view with the same\n\u003e code.\n\n## Registering PDF templates and layouts\n\nPDF views can be registered as templates that are automatically generated in the back-end ready for customization. PDF\ntemplates can be customized via the *Settings \u003e PDF Templates* menu. The templates can be registered by adding\nthe `registerPDFTemplates` method of the Plugin registration class (`Plugin.php`).\n\n```\npublic function registerPDFTemplates()\n{\n    return [\n        'renatio.demo::pdf.invoice',\n        'renatio.demo::pdf.resume',\n    ];\n}\n```\n\nThe method should return an array of pdf view names.\n\nLike templates, PDF layouts can be registered by adding the `registerPDFLayouts` method of the Plugin registration\nclass (`Plugin.php`).\n\n```\npublic function registerPDFLayouts()\n{\n    return [\n        'renatio.demo::pdf.layouts.invoice',\n        'renatio.demo::pdf.layouts.resume',\n    ];\n}\n```\n\nThe method should return an array of pdf view names.\n\n## Usage\n\nPDF templates and layouts can be accessed in the back-end area via *Settings \u003e PDF \u003e PDF Templates*.\n\nLayouts define the PDF scaffold, that is everything that repeats on a PDF, such as a header and footer. Each layout has\nunique code, optional background image, HTML content and CSS/LESS content. Not all CSS properties are supported, so\ncheck [CSSCompatibility](https://github.com/dompdf/dompdf/wiki/CSSCompatibility).\n\nTemplates define the actual PDF content parsed from HTML.\n\n## Configuration\n\nThe default configuration settings are set in `config/dompdf.php`. Copy this file to your own config directory to modify\nthe values. You can publish the config using this command:\n\n```\nphp artisan vendor:publish --provider=\"Barryvdh\\DomPDF\\ServiceProvider\"\n```\n\nYou can still alter the dompdf options in your code before generating the PDF using dynamic methods for all options like\nso:\n\n```\nPDF::loadTemplate('renatio::invoice')\n    -\u003esetDpi(300)\n    -\u003esetDefaultFont('sans-serif')\n    -\u003estream();\n```\n\nor you can use `setOption` method before generating the pdf using this command:\n\n```\nPDF::loadTemplate('renatio::invoice')\n    -\u003esetOption(['dpi' =\u003e 300, 'defaultFont' =\u003e 'sans-serif'])\n    -\u003estream();\n```\n\nAvailable options and their defaults:\n\n* __rootDir__: \"{app_directory}/vendor/dompdf/dompdf\"\n* __tempDir__: \"/tmp\" _(available in config/dompdf.php)_\n* __fontDir__: \"{app_directory}/storage/fonts/\" _(available in config/dompdf.php)_\n* __fontCache__: \"{app_directory}/storage/fonts/\" _(available in config/dompdf.php)_\n* __chroot__: \"{app_directory}\" _(available in config/dompdf.php)_\n* __logOutputFile__: \"/tmp/log.htm\"\n* __defaultMediaType__: \"screen\" _(available in config/dompdf.php)_\n* __defaultPaperSize__: \"a4\" _(available in config/dompdf.php)_\n* __defaultFont__: \"serif\" _(available in config/dompdf.php)_\n* __dpi__: 96 _(available in config/dompdf.php)_\n* __fontHeightRatio__: 1.1 _(available in config/dompdf.php)_\n* __isPhpEnabled__: false _(available in config/dompdf.php)_\n* __isRemoteEnabled__: true _(available in config/dompdf.php)_\n* __isJavascriptEnabled__: true _(available in config/dompdf.php)_\n* __isHtml5ParserEnabled__: false _(available in config/dompdf.php)_\n* __isFontSubsettingEnabled__: false _(available in config/dompdf.php)_\n* __debugPng__: false\n* __debugKeepTemp__: false\n* __debugCss__: false\n* __debugLayout__: false\n* __debugLayoutLines__: true\n* __debugLayoutBlocks__: true\n* __debugLayoutInline__: true\n* __debugLayoutPaddingBox__: true\n* __pdfBackend__: \"CPDF\" _(available in config/dompdf.php)_\n* __pdflibLicense__: \"\"\n* __adminUsername__: \"user\"\n* __adminPassword__: \"password\"\n\nSee [Dompdf\\Options](https://github.com/dompdf/dompdf/blob/master/src/Options.php) for a list of available options.\n\n## Methods\n\n| Method                                                  | Description                                              |\n|---------------------------------------------------------|----------------------------------------------------------|\n| loadTemplate($code, array $data = [], $encoding = null) | Load backend template                                    |\n| loadLayout($code, array $data = [], $encoding = null)   | Load backend layout                                      |\n| loadHTML($string, $encoding = null)                     | Load HTML string                                         |\n| loadFile($file)                                         | Load HTML string from a file                             |\n| parseTemplate(Template $template, array $data = [])     | Parse backend template using Twig                        |\n| parseLayout(Layout $layout, array $mergeData = [])      | Parse backend layout using Twig                          |\n| getDomPDF()                                             | Get the DomPDF instance                                  |\n| setPaper($paper, $orientation = 'portrait')             | Set the paper size and orientation (default A4/portrait) |\n| setWarnings($warnings)                                  | Show or hide warnings                                    |\n| output()                                                | Output the PDF as a string                               |\n| save($filename)                                         | Save the PDF to a file                                   |\n| download($filename = 'document.pdf')                    | Make the PDF downloadable by the user                    |\n| stream($filename = 'document.pdf')                      | Return a response with the PDF to show in the browser    |\n\nAll methods are available through Facade class `Renatio\\DynamicPDF\\Classes\\PDF`.\n\n## Tips\n\n### Background image\n\nTo display background image added in layout use following code:\n\n```\n\u003cbody style=\"background: url({{ background_img }}) top left no-repeat;\"\u003e\n```\n\nBackground image should be at least 96 DPI size (793 x 1121 px).\n\nIf you want to use better quality image like 300 DPI (2480 x 3508 px) than you need to change template options like so:\n\n```\nreturn PDF::loadTemplate($model-\u003ecode)\n    -\u003esetDpi(300)\n    -\u003estream();\n```\n\n### UTF-8 support\n\nIn your layout, set the UTF-8 meta tag in `head` section:\n\n```\n\u003cmeta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/\u003e\n```\n\nIf you have problems with foreign characters than try to use **DejaVu Sans** font family.\n\n### Page breaks\n\nYou can use the CSS page-break-before/page-break-after properties to create a new page.\n\n```\n\u003cstyle\u003e\n.page-break {\n    page-break-after: always;\n}\n\u003c/style\u003e\n\u003ch1\u003ePage 1\u003c/h1\u003e\n\u003cdiv class=\"page-break\"\u003e\u003c/div\u003e\n\u003ch1\u003ePage 2\u003c/h1\u003e\n```\n\n### Open basedir restriction error\n\nOn some hosting providers there were reports about `open_basedir` restriction problems with log file. You can change\ndefault log file destination like so:\n\n```\nreturn PDF::loadTemplate('renatio::invoice')\n    -\u003esetLogOutputFile(storage_path('temp/log.htm'))\n    -\u003estream();\n```\n\n### Embed image inside PDF template\n\nYou can use absolute path for image eg. `https://app.dev/path_to_your_image`.\n\nFor this to work you must set `isRemoteEnabled` option.\n\n```\nreturn PDF::loadTemplate('renatio::invoice', ['file' =\u003e $file])\n    -\u003esetIsRemoteEnabled(true)\n    -\u003estream();\n```\n\nI assume that `$file` is instance of `October\\Rain\\Database\\Attach\\File`.\n\nThen in the template you can use following example code:\n\n```\n{{ file.getPath }}\n\n{{ file.getLocalPath }}\n\n{{ file.getThumb(200, 200, {'crop' =\u003e true}) }}\n```\n\n\u003e For retrieving stylesheets or images via http following PHP setting must be enabled `allow_url_fopen`.\n\nWhen `allow_url_fopen` is disabled on server try to use relative path. You can use October `getLocalPath` function on\nthe file object to retrieve it.\n\n### Download PDF via Ajax response\n\nOctoberCMS ajax framework cannot handle this type of response.\n\nRecommended approach is to save PDF file locally and return redirect to PDF file.\n\n### Page numbers\n\nPage numbers can be generated using PHP. Inline PHP is disabled by default, because it can be a security risk. You can\nenable inline PHP using `setIsPhpEnabled` method.\n\n```\nreturn PDF::loadTemplate('renatio::invoice')\n    -\u003esetIsRemoteEnabled(true)\n    -\u003esetIsPhpEnabled(true)\n    -\u003estream();\n```\n\nAfter that you must place following code before closing `\u003c/body\u003e` tag of the layout file.\n\n```\n\u003cscript type=\"text/php\"\u003e\n    if (isset($pdf)) {\n        $size = 9;\n        $color = [0,0,0];\n\n        $font = $fontMetrics-\u003egetFont('Open Sans');\n        $textHeight = $fontMetrics-\u003egetFontHeight($font, $size);\n        $width = $fontMetrics-\u003egetTextWidth('Page 1 of 2', $font, $size);\n\n        $foot = $pdf-\u003eopen_object();\n\n        $w = $pdf-\u003eget_width();\n        $h = $pdf-\u003eget_height();\n\n        $y = $h - $textHeight - 13;\n\n        $pdf-\u003eclose_object();\n        $pdf-\u003eadd_object($foot, 'all');\n\n        $text = \"Page {PAGE_NUM} of {PAGE_COUNT}\";\n\n        // Center the text\n        $pdf-\u003epage_text($w / 2 - $width / 2, $y, $text, $font, $size, $color);\n    }\n\u003c/script\u003e\n```\n\n## Examples\n\n### Demo examples\n\nThere is a console command that will enable demo templates and layouts.\n\n```\nphp artisan dynamicpdf:demo\n```\n\nTo disable demo run following command:\n\n```\nphp artisan dynamicpdf:demo --disable\n```\n\nThe first example shows invoice with custom font and image embed.\n\nThe second example shows usage of header \u0026 footer, page break, page numbers and full background image.\n\n### Render PDF in browser\n\n```\nuse Renatio\\DynamicPDF\\Classes\\PDF; // import facade\n\npublic function pdf()\n{\n    $templateCode = 'renatio::invoice'; // unique code of the template\n    $data = ['name' =\u003e 'John Doe']; // optional data used in template\n\n    return PDF::loadTemplate($templateCode, $data)-\u003estream('download.pdf');\n}\n```\n\nWhere `$templateCode` is an unique code specified when creating the template, `$data` is optional array of twig fields\nwhich will be replaced in template.\n\nIn HTML template you can use `{{ name }}` to output `John Doe`.\n\n### Download PDF\n\n```\nuse Renatio\\DynamicPDF\\Classes\\PDF;\n\npublic function pdf()\n{\n    return PDF::loadTemplate('renatio::invoice')-\u003edownload('download.pdf');\n}\n```\n\n### Fluent interface\n\nYou can chain the methods:\n\n```\nreturn PDF::loadTemplate('renatio::invoice')\n    -\u003esave('/path-to/my_stored_file.pdf')\n    -\u003estream();\n```\n\n### Change paper size and orientation\n\n```\nreturn PDF::loadTemplate('renatio::invoice')\n    -\u003esetPaper('a4', 'landscape')\n    -\u003estream();\n```\n\nAvailable [paper sizes](https://github.com/dompdf/dompdf/blob/master/src/Adapter/CPDF.php#L40).\n\n### PDF on CMS page\n\nTo display PDF on CMS page you can use PHP section of the page like so:\n\n```\nuse Renatio\\DynamicPDF\\Classes\\PDF;\n\nfunction onStart()\n{\n    return PDF::loadTemplate('renatio::invoice')-\u003estream();\n}\n```\n\n### Header and footer on every page\n\n```\n\u003chtml\u003e\n\u003chead\u003e\n  \u003cstyle\u003e\n    @page { margin: 100px 25px; }\n    header { position: fixed; top: -60px; left: 0px; right: 0px; background-color: lightblue; height: 50px; }\n    footer { position: fixed; bottom: -60px; left: 0px; right: 0px; background-color: lightblue; height: 50px; }\n    p { page-break-after: always; }\n    p:last-child { page-break-after: never; }\n  \u003c/style\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n  \u003cheader\u003eheader on each page\u003c/header\u003e\n  \u003cfooter\u003efooter on each page\u003c/footer\u003e\n  \u003cmain\u003e\n    \u003cp\u003epage1\u003c/p\u003e\n    \u003cp\u003epage2\u003c/p\u003e\n  \u003c/main\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n### Using custom fonts\n\nPlugin provides \"Open Sans\" font, which can be imported in Layout CSS section.\n\n```\n@font-face {\n    font-family: 'Open Sans';\n    src: url({{ 'plugins/renatio/dynamicpdf/assets/fonts/OpenSans-Regular.ttf'|app }});\n}\n\n@font-face {\n    font-family: 'Open Sans';\n    font-weight: bold;\n    src: url({{ 'plugins/renatio/dynamicpdf/assets/fonts/OpenSans-Bold.ttf'|app }});\n}\n\n@font-face {\n    font-family: 'Open Sans';\n    font-style: italic;\n    src: url({{ 'plugins/renatio/dynamicpdf/assets/fonts/OpenSans-Italic.ttf'|app }});\n}\n\n@font-face {\n    font-family: 'Open Sans';\n    font-style: italic;\n    font-weight: bold;\n    src: url({{ 'plugins/renatio/dynamicpdf/assets/fonts/OpenSans-BoldItalic.ttf'|app }});\n}\n\nbody {\n    font-family: 'Open Sans', sans-serif;\n    font-size: 16px;\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmplodowski%2Fdynamicpdf-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmplodowski%2Fdynamicpdf-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmplodowski%2Fdynamicpdf-plugin/lists"}