I'm using TCPDF to create pdf files, but, since the CSS support is missing, I was working to theme my output with print.tpl.php.
My main problem is that all CCK fields are not formatted (labels are not displayed inline, text is not properly alligned, etc..) so I thought to hard code some html tag to force this styles.
I was wondering if it is possible to override the content-field.tpl.php of CCK just for the pdf output, creating a file like print.content-field.tpl.php or something like that.
Thanks in advance for your suggestions.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jcnventura’s picture

Title: Theming CCK without CSS » Modifying CCK fields HTML for a better layout in TCPDF
Status: Active » Postponed (maintainer needs more info)

Hi,

The print.content-field.tpl.php ideia is not possible. By the time that the templating scheme in the module comes up, the content of Drupal's original node has already been rendered. The module uses drupal_render() for the content generation, and to do what you need would complicate A LOT the code.

However, you can still use some preg_replace() inside the print.tpl.php to replace the HTML coming from Drupal (and CCK) with something simpler that TCPDF understands.

I wish you good luck,

João

PS: If you come up with a nice solution, please share it with the rest of us.

upupax’s picture

Sorry for boring you again, but I was still thinking how improving this module (cause I think it's unique).
I first didn't understand, but after giving a look at your code I get what you mean..
I've seen you used the preg_match function to clean the original HTML output before printing the pdf file with TCPDF, so I'll check if I can use the same solution in my case.

I then tried DOMPDF, but I've encountered the unicode problems (as you say in documentation) especially for quotes and the € symbol: do you think it would be possible to introduce unicode support in it? Googling I've found people that say it is possible to improve the utf-8 support for dompdf with this (http://freshmeat.net/projects/convertcharacterset/): do you think it could be a possible solution?

Thanks again, always in advance!

jcnventura’s picture

All that I could do address this situation (converting some chars into ISO-8859-1), I already did..

True Unicode must use TCPDF or (it seems) dompdf + the commercial version of pdflib.

That seems to be the current quandary about the available PDF tools: you either get 'decent' HTML rendering or Unicode. You can't easily have both.

João

upupax’s picture

Thanks! Now I figured it out!
I think I'll try to use preg_match or preg_replace to change all the classes "field-label" to html tags to have a better pdf output.
I'll work on it and I'll let you know!

joostvdl’s picture

Subscribing

joostvdl’s picture

Hereby an example of a CCK field "Datum". When used the Print option it is correctly rendered (see attachment: Newsletter_created_via_Print_button.pdf). But when the same node is created via de PDF button the CCK field is not rendered like it has to be (see attachment: Newsletter_created via_PDF_button.pdf)

joostvdl’s picture

ow... I see now also that the file created with the PDF option is almost 10 times as large as the locally created PDF with the printdriver :-(

jcnventura’s picture

In your case, you're using a European language, so a non-Unicode font is perfectly acceptable.

The module uses dejavusans by default (a Unicode font). If you specify helvetica as the font in "admin/settings/print/pdf", you'll get a much smaller PDF.

This is a problem with TCPDF embedding the WHOLE font in the PDF, instead of the (more normal) method of just embedding the characters actually used. Helvetica is one of the fonts included with Adobe Reader (and every other sane PDF reader), so that one doesn't need to be embedded.

As to the field formatting, this is the HTML code in your page:

    <div class="field-items">
            <div class="field-item odd">
                      <div class="field-label-inline-first">
              Datum:&nbsp;</div>
                    <span class="date-display-single">10 Maart 2009</span>        </div>
        </div>

The imperfect support of CSS by TCPDF doesn't let it recognize the fact that that class means that the date value is to be inline.. Also, it is actually rendering all the spaces present in the HTML..
What is needed here is some preg_replace() magic to get rid of the div (replace it with a strong tag??) and the spaces.

I am willing to make this a part of the code, as long as someone can come up with something that works for any regular use of the CCK fields.

João

joostvdl’s picture

It's difficult with CCK fields and formatting. Everybody does their own formating of the CCK fields and labels. So a replace with a strong is not a final solution I think.

To remove the spaces is a first step and make it inline when needed a second step. But how to handle other css settings?

upupax’s picture

Ok, this is what I think.
1° issue: the output is "indent-sensitive" (the pdf reflect how the code is indented), I solved this with a preg_replace('!^[ \t]+!', '', $html); (thank you jcnventura for the suggestion);
2° issue: even if I'm italian, I had problems with some characters with dompdf (like € and ').

I was thinking how to improve this module and I think that give a larger set of variables to use in the tpl.php file would be an idea.
Since now I used preg_match_all('/field-field-.*">/',$print['content'], $found); to find all div that contain a cck field.
Knowing this (but maybe it's only in my mind) since every field has a <div class="field-label"> and a <div class="field-item"> it would be possible to create an array like $match_field['field_name']=$field_content.
I know this is just the standard configuration for cck, but it would be a starting point, no?
I'm just brainstorming, so if I'm saying useless things, please tell me.

jcnventura’s picture

The pattern in the preg_replace to remove the indenting would be better to search for all whitespace (\s) coming after an opening div tag (!<div[^>*]>(\s)!).

Unfortunately, as I explained in #1 above, the $print['content'] is already the lowest granularity possible after the drupal_render() call.

However, nothing prevents the module (or the code in the template) to call the cck module directly to get the fields and respective values. I think its overkill, though. It seems possible to simply search for the div with field-label and to replace those tags with a strong tag.

João

upupax’s picture

The #11 pattern works great for tabs and whitespaces.
I've replaced field-label div's with strong using
$print['content'] = preg_replace ('!<div class=\"field-label\">(.*)</div>!', '<strong>$1</strong>', $print['content']);
Now I would like to remove useless linebreaks (I have a couple of them after every tag). I tried different patterns with no success: can you help me again?

jcnventura’s picture

Status: Postponed (maintainer needs more info) » Fixed

Just committed some code that fixes this. It should be available in the latest dev in a few hours.

upupax’s picture

Just tested! This is really better than before! Thanks!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.