Stack Exchange Network
Stack Exchange network consists of 183 Q&A communities including
Stack Overflow
, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.
Visit Stack Exchange
Joomla Stack Exchange is a question and answer site for Joomla! administrators, users, developers and designers. It only takes a minute to sign up.
Sign up to join this community
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I'm trying to create a Joomla system plugin enabling a user to generate a pdf based on a template. I'm using the
Dompdf
library. I managed to create a PDF, but linking to an
external css file
isn't working.
I have tried using the setBasePath with these parameters in my Helper.php file:
private static $template_directory = 'media' . DS . 'plg_system_pdfgenerator' . DS . 'template';
setBasePath(JPATH_ROOT . DS . self::$template_directory . DS . 'css' . DS);
setBasePath(Uri::root() . DS . self::$template_directory . DS . 'css' . DS);
and in my template with .php or .html extension, I'm using:
<link type="text/css" rel="stylesheet" href="style.css" />
I have also tried appending Uri::root()
, using DOMDocument. It works for anchors and did work for images locally, but not on the server (I will make another request for this question) :
$doc = new DOMDocument();
libxml_use_internal_errors(true);
$doc->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
$linkTags = $doc->getElementsByTagName('link');
foreach ($linkTags as $linkTag) {
if ($linkTag->getAttribute('rel') === 'stylesheet') {
$stylesheet = $linkTag;
$href = Uri::root() . $stylesheet->getAttribute('href');
// if href is referenced by absolute path
if (str_contains($href, '//')) {
$href = str_replace('//', '/', $href);
$stylesheet->setAttribute('href', $href);
// returns false if an error occured
$response = $doc->saveHTML();
In which case I tried using:
<link type="text/css" rel="stylesheet" href="media/plg_system_pdfgenerator/template/css/style.css" />
<link type="text/css" rel="stylesheet" href="/media/plg_system_pdfgenerator/template/css/style.css" />
For now this is my code instantiating the Dompdf library, not using the DOMDocument for my stylesheet :
// create pdf
$dompdf = new Dompdf(['isHtml5ParserEnabled' => true, 'isRemoteEnabled' => true]);
$dompdf->setBasePath(JPATH_ROOT . self::$template_directory . DS . 'css' . DS);
$dompdf->loadHtml($html, 'utf-8');
$dompdf->setPaper('A4', 'portrait');
$dompdf->render();
// save pdf
$output = $dompdf->output();
try {
$response = @file_put_contents(JPATH_ROOT . DS . self::$pdf_storage . DS . $item->alias . '.pdf', $output, LOCK_EX);
} catch (\Throwable $th) {
Log::add($th->getMessage(), Log::ERROR, self::$extension);
And this is the template's code:
<link type="text/css" href="style.css" rel="stylesheet" />
</head>
</body>
</html>
Ok so finaly I've found what wasn't working out and managed to get it to work without the basePath and with the use of DOMDocument.
This is what I was doing wrong in my code, and also why I was having trouble with the images :
$href = Uri::root() . $stylesheet->getAttribute('href');
if (str_contains($href, '//')) {
// this doesn't work since it is getting rid of the '//' in http://
$href = str_replace('//', '/', $href);
So I have replaced it with this :
$uri = Uri::getInstance();
// check if path is absolute
if (strpos($stylesheet->getAttribute('href'), '/') === 0) {
$href = $uri->getScheme() . '://' . $uri->getHost() . $stylesheet->getAttribute('href');
I really created a function to manage different tags wich have src or href attribute, but for the sake of staying coherent I replaced it with $stylesheet for my answer.
Someone else was kind enough to give me this answer aswell but I haven't tried it out :
Add dompdf option 'chroot' with value of JPATH_SITE
All src="xxx" or href="xxx" attribs should use the full image file name, not link, i.e. src="/home/www/site/com/images/img.jpg". You
should convert URLs in src/href attrib to full filenames.
Thanks for contributing an answer to Joomla Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.