HTML to PDF using wkhtmltopdf

Converting web pages to PDF? Sick of various libs and their various quirks and complexity? Wkhtmltopdf is a linux program that can reliably generate pdfs from html content. It’s as easy as running:

wkhtmltopdf http://google.com google.pdf

from the command line. However, we want it in our web site! First off though, you’ll need it installed. If you are using puPHPet and vagrant, add the following in your config.yaml under server: packages:

server:
    install: '1'
    packages:
        - wkhtmltopdf

Then run vagrant provision. Standard linux servers will install by using yum or apt-get:

sudo apt-get install wkhtmltopdf

You can get the PHP wrapper class here:

https://github.com/mikehaertl/phpwkhtmltopdf

From within your PHP, you can say:

        use mikehaert\wkhtmlto\Pdf;

        $pdf = new Pdf(array('tmpDir' => '/optional/tmp/folder/here'));
        $pdf->addPage('http://google.com');

        // Save the PDF
        // $pdf->saveAs('/tmp/new.pdf');

        // ... or send to client for inline display
        if (!$pdf->send()) {echo $pdf->getError();}
        
        // ... or send to client as file download
        // $pdf->send('test.pdf');

You may get an error saying it cannot connect to the X server. If you get this, you probably don’t have X installed! I didn’t, it’s a web server, not a desktop machine!

In the event that you have no X server, go into the Command.php class, you will see the following option:

    /**
     * @var bool whether to enable the built in Xvfb support (uses xvfb-run)
     */
    public $enableXvfb = false;

Change this to true, and try again. This time it should work!

If it still doesn’t, then possibly you also need to install xvfb, again with apt-get or yum, then add a startup script for it. I didn’t have to do any of this, but for those of you who may need to, complete the following steps:

sudo nano /etc/init.d/xvfb

XVFB=/usr/bin/Xvfb
XVFBARGS=":0 -screen 0 1024x768x24 -ac +extension GLX +render -noreset"
PIDFILE=/var/run/xvfb.pid
case "$1" in
  start)
    echo -n "Starting virtual X frame buffer: Xvfb"
    start-stop-daemon --chuid www-data --start --quiet --pidfile $PIDFILE --make-pidfile --background --exec $XVFB -- $XVFBARGS
    echo "."
    ;;
  stop)
    echo -n "Stopping virtual X frame buffer: Xvfb"
    start-stop-daemon --chuid www-data --stop --quiet --pidfile $PIDFILE
    echo "."
    ;;
  restart)
    $0 stop
    $0 start
    ;;
  *)
        echo "Usage: /etc/init.d/xvfb {start|stop|restart}"
        exit 1
esac

exit 0

Enable the init script:

update-rc.d xvfb defaults 10

Start it up:

/etc/init.d/xvfb start

Check its running:

ps auxU www-data | grep [X]vfb

Now try reloading your page, and with a bit of luck you should see a PDF version of the google home page! Play around with it and have fun!

Advertisements

Using Emmet in your IDE

Emmet is awesome! It’s a little tool (once called Zen Coding) that gives you loads of keyboard shortcuts for generating HTML and CSS markup! Give it a try! Install an Emmet plugin into your IDE. Then, in a view file, try typing this:

table#applications.table-striped.table-hover.table>thead>tr>td*3^^tbody>tr>td*

In PHPStorm, hit TAB after typing that. In Eclipse/Aptana, you press CTRL-E. Suddenly, it changes to:

<table id="applications" class="table-striped table-hover table">
    <thead>
        <tr>
            <td></td>
            <td></td>
            <td></td>
         </tr>
    </thead>
    <tbody>
         <tr>
             <td></td>
             <td></td>
             <td></td>
         </tr>
    </tbody>
</table>

As you can imagine, this saves a LOT of time! Check out the Emmet Cheatsheet here:
http://docs.emmet.io/cheat-sheet/

You can download the plugin for your IDE here:
http://emmet.io/download/
Have fun!

iOS Web App Icons and Loading Screens

There’s a stack of different icon sizes and splash screen sizes now, depending which iPod, iPhone, or iPad you are using. iPad can also splash screen in Landscape, iPhone 5 has a different aspect ratio, etc! It has been a while since I last made web app icons etc, so I brought myself up to speed, and found the following Gist on Github:

Very handy 🙂

<!– Run in full-screen mode. –>
<meta name=“apple-mobile-web-app-capable” content=“yes”>
<!– Make the status bar black with white text. –>
<meta name=“apple-mobile-web-app-status-bar-style” content=“black”>
<!– Customize home screen title. –>
<meta name=“apple-mobile-web-app-title” content=“Web App”>
<!– Disable phone number detection. –>
<meta name=“format-detection” content=“telephone=no”>
<!– Set viewport. –>
<meta name=“viewport” content=“initial-scale=1”>
<!– Prevent text size adjustment on orientation change. –>
<style>html { webkittextsizeadjust: 100%; }</style>
<title>iOS 7 Web App</title>
<!– Icons –>
<!– iOS 7 iPad (retina) –>
<link href=“/static/images/apple-touch-icon-152×152.png”
sizes=“152×152”
rel=“apple-touch-icon”>
<!– iOS 6 iPad (retina) –>
<link href=“/static/images/apple-touch-icon-144×144.png”
sizes=“144×144”
rel=“apple-touch-icon”>
<!– iOS 7 iPhone (retina) –>
<link href=“/static/images/apple-touch-icon-120×120.png”
sizes=“120×120”
rel=“apple-touch-icon”>
<!– iOS 6 iPhone (retina) –>
<link href=“/static/images/apple-touch-icon-114×114.png”
sizes=“114×114”
rel=“apple-touch-icon”>
<!– iOS 7 iPad –>
<link href=“/static/images/apple-touch-icon-76×76.png”
sizes=“76×76”
rel=“apple-touch-icon”>
<!– iOS 6 iPad –>
<link href=“/static/images/apple-touch-icon-72×72.png”
sizes=“72×72”
rel=“apple-touch-icon”>
<!– iOS 6 iPhone –>
<link href=“/static/images/apple-touch-icon-57×57.png”
sizes=“57×57”
rel=“apple-touch-icon”>
<!– Startup images –>
<!– iOS 6 & 7 iPad (retina, portrait) –>
<link href=“/static/images/apple-touch-startup-image-1536×2008.png”
media=“(device-width: 768px) and (device-height: 1024px)
and (orientation: portrait)
and (-webkit-device-pixel-ratio: 2)”
rel=“apple-touch-startup-image”>
<!– iOS 6 & 7 iPad (retina, landscape) –>
<link href=“/static/images/apple-touch-startup-image-1496×2048.png”
media=“(device-width: 768px) and (device-height: 1024px)
and (orientation: landscape)
and (-webkit-device-pixel-ratio: 2)”
rel=“apple-touch-startup-image”>
<!– iOS 6 iPad (portrait) –>
<link href=“/static/images/apple-touch-startup-image-768×1004.png”
media=“(device-width: 768px) and (device-height: 1024px)
and (orientation: portrait)
and (-webkit-device-pixel-ratio: 1)”
rel=“apple-touch-startup-image”>
<!– iOS 6 iPad (landscape) –>
<link href=“/static/images/apple-touch-startup-image-748×1024.png”
media=“(device-width: 768px) and (device-height: 1024px)
and (orientation: landscape)
and (-webkit-device-pixel-ratio: 1)”
rel=“apple-touch-startup-image”>
<!– iOS 6 & 7 iPhone 5 –>
<link href=“/static/images/apple-touch-startup-image-640×1096.png”
media=“(device-width: 320px) and (device-height: 568px)
and (-webkit-device-pixel-ratio: 2)”
rel=“apple-touch-startup-image”>
<!– iOS 6 & 7 iPhone (retina) –>
<link href=“/static/images/apple-touch-startup-image-640×920.png”
media=“(device-width: 320px) and (device-height: 480px)
and (-webkit-device-pixel-ratio: 2)”
rel=“apple-touch-startup-image”>
<!– iOS 6 iPhone –>
<link href=“/static/images/apple-touch-startup-image-320×460.png”
media=“(device-width: 320px) and (device-height: 480px)
and (-webkit-device-pixel-ratio: 1)”
rel=“apple-touch-startup-image”>

	

Consistent HTML Emails for Outlook compatibility

If you’ve ever had to send out emails to a marketing list or what have you, no doubt you’ve lost hair, pulling it out, and lost enamel grinding your teeth thanks to the worlds worst browser provider – Microsoft.

You should always remember the following:

  • Use old fashioned tables, not divs, for laying stuff out
  • dont include css, always use style=”whatever”
  • set cellspacing and cellpadding to 0
  • border=”0″ on your images with links
  • Use tables within tables, make your main table have one <td> in a row
  • if you are using colspan read the previous point
  • style your <a> tags or they’ll be that stinking default blue
  • following worldwide recognised and established coding standards will break outlook
  • Padding will screw up Outlook

The last point is the main reason IE etc is the worst, I have no idea why 13 or more years down the line they still cant get this right!
Padding for some stupid reason gets added to the outside of our box model rather than the inside. The best way to get round this? Shove a div inside whichever <td> you are in. Padding that will still screw up, so use margin instead.

If anyone else has any tips to spare the innocent developers from the Wrath of Gates, feel free to drop a comment!

And now for a short rant:

MICROSOFT SORT YOUR SH*T OUT! WE’VE PUT UP WITH THIS LONG ENOUGH!
If you work for Microsoft, I hate you. Unless you convince whoever THE F*CK programs IE and Outlook to follow this link:

http://www.w3.org/TR/1999/REC-html401-19991224/

WRITTEN IN 1999 !!!!!!!!!!!!!!!!!