<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Code-It &#187; Web Development</title>
	<atom:link href="http://lois.di-qual.net/blog/category/web-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://lois.di-qual.net/blog</link>
	<description></description>
	<lastBuildDate>Tue, 30 Oct 2012 19:19:29 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Django &#8211; UnicodeDecodeError using i18n</title>
		<link>http://lois.di-qual.net/blog/django-unicodedecodeerror-using-i18n/</link>
		<comments>http://lois.di-qual.net/blog/django-unicodedecodeerror-using-i18n/#comments</comments>
		<pubDate>Mon, 30 Jul 2012 21:32:11 +0000</pubDate>
		<dc:creator>Loïs Di Qual</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[UnicodeDecodeError]]></category>

		<guid isPermaLink="false">http://lois.di-qual.net/blog/?p=83</guid>
		<description><![CDATA[If you&#8217;re using i18n in your django website, you may encounter this issue. It took me two hours to find where the problem came from: you have to use ugettext instead of gettext if your translated strings contains non-ascii characters. gettext => ugettext With gettext: 12345from django.utils.translation import gettext as _ define my_view&#40;request&#41;: &#160; &#160; [...]]]></description>
				<content:encoded><![CDATA[<p>If you&#8217;re using i18n in your django website, you may encounter this issue. It took me two hours to find where the problem came from: you have to use <code class="codecolorer text default"><span class="text">ugettext</span></code> instead of <code class="codecolorer text default"><span class="text">gettext</span></code> if your translated strings contains non-ascii characters.</p>
<p><span id="more-83"></span></p>
<h2>gettext => ugettext</h2>
<p>With <code class="codecolorer text default"><span class="text">gettext</span></code>:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">utils</span>.<span style="color: black;">translation</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">gettext</span> <span style="color: #ff7700;font-weight:bold;">as</span> _<br />
<br />
define my_view<span style="color: black;">&#40;</span>request<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> _<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Here comes nothing&quot;</span><span style="color: black;">&#41;</span> // Prints <span style="color: #483d8b;">&quot;Here comes nothing&quot;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> _<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Here comes something spécial&quot;</span><span style="color: black;">&#41;</span> // Raises a <span style="color: #008000;">UnicodeDecodeError</span> because <span style="color: #483d8b;">&quot;é&quot;</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">unicode</span></div></td></tr></tbody></table></div>
<p>With <code class="codecolorer text default"><span class="text">ugettext</span></code>:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">utils</span>.<span style="color: black;">translation</span> <span style="color: #ff7700;font-weight:bold;">import</span> ugettext <span style="color: #ff7700;font-weight:bold;">as</span> _<br />
<br />
define my_view<span style="color: black;">&#40;</span>request<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> _<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Here comes nothing&quot;</span><span style="color: black;">&#41;</span> // Prints <span style="color: #483d8b;">&quot;Here comes nothing&quot;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> _<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Here comes something spécial&quot;</span><span style="color: black;">&#41;</span> // Prints <span style="color: #483d8b;">&quot;Here comes something spécial&quot;</span></div></td></tr></tbody></table></div>
<h2>ugettext or ugettext_lazy ?</h2>
<p>Two simple rules:</p>
<ul>
<li>Use <code class="codecolorer text default"><span class="text">ugettext_lazy</span></code> in global scopes (model fields, django settings, everything not wrapped by a function or method, &#8230;)</li>
<li>Use <code class="codecolorer text default"><span class="text">ugettext</span></code> everywhere else (in views, methods, functions, &#8230;)</li>
</ul>
<p>That&#8217;s it !</p>
]]></content:encoded>
			<wfw:commentRss>http://lois.di-qual.net/blog/django-unicodedecodeerror-using-i18n/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django &#8211; Absolute media URIs from templates</title>
		<link>http://lois.di-qual.net/blog/django-absolute-media-uris-from-templates/</link>
		<comments>http://lois.di-qual.net/blog/django-absolute-media-uris-from-templates/#comments</comments>
		<pubDate>Mon, 16 Jul 2012 21:54:17 +0000</pubDate>
		<dc:creator>Loïs Di Qual</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://lois.di-qual.net/blog/?p=74</guid>
		<description><![CDATA[Sometimes, you need to build an absolute URI to a media file from your templates: 1http://example.com/media/sample.jpg After following this small tutorial, you&#8217;ll be able to do this: 12{% load mytemplatetags %} {{ media_name&#124;absolute_media_url:request }} Settings In urls.py, in urlpatterns, add a reverse name to the media URL: 123456urlpatterns = patterns&#40;'', &#160; &#160; # Before &#160; [...]]]></description>
				<content:encoded><![CDATA[<p>Sometimes, you need to build an absolute URI to a media file from your templates:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">http://example.com/media/sample.jpg</div></td></tr></tbody></table></div>
<p>After following this small tutorial, you&#8217;ll be able to do this:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">{% load mytemplatetags %}<br />
{{ media_name|absolute_media_url:request }}</div></td></tr></tbody></table></div>
<p><span id="more-74"></span></p>
<h2>Settings</h2>
<p>In <code class="codecolorer text default"><span class="text">urls.py</span></code>, in <code class="codecolorer text default"><span class="text">urlpatterns</span></code>, add a reverse name to the media URL:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">urlpatterns <span style="color: #66cc66;">=</span> patterns<span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Before</span><br />
&nbsp; &nbsp; <span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^media/(?P&lt;path&gt;.*)$'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'django.views.static.serve'</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'document_root'</span>: settings.<span style="color: black;">MEDIA_ROOT</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># After</span><br />
&nbsp; &nbsp; url<span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^media/(?P&lt;path&gt;.*)$'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'django.views.static.serve'</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'document_root'</span>: settings.<span style="color: black;">MEDIA_ROOT</span><span style="color: black;">&#125;</span><span style="color: #66cc66;">,</span> name<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;media&quot;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
<span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>You can now reverse media files using <code class="codecolorer text default"><span class="text">request.build_absolute_uri(reverse('media', args=['/path/to/media']))</span></code>.</p>
<p>In <code class="codecolorer text default"><span class="text">settings.py</span></code>, add <code class="codecolorer text default"><span class="text">django.core.context_processors.request</span></code> to <code class="codecolorer text default"><span class="text">TEMPLATE_CONTEXT_PROCESSORS</span></code>.</p>
<p>This context processor allows you to access the <code class="codecolorer text default"><span class="text">request.build_absolute_uri()</span></code> function from templates:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: black;">&#123;</span><span style="color: black;">&#123;</span> request.<span style="color: black;">build_absolute_uri</span> <span style="color: black;">&#125;</span><span style="color: black;">&#125;</span></div></td></tr></tbody></table></div>
<p>However, you can&#8217;t pass parameters to this function, so you won&#8217;t be able to reverse media path to URL. That&#8217;s why we need a filter.</p>
<h2>Absolute url for a media</h2>
<p>The following filter will allow you to build an absolute URL to a media. In <code class="codecolorer text default"><span class="text">templatetags/mytemplatetags.py</span></code>:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #483d8b;">'''<br />
Usage: {{ media|absolute_media_url:request }}<br />
'''</span><br />
<span style="color: #66cc66;">@</span>register.<span style="color: #008000;">filter</span><br />
<span style="color: #ff7700;font-weight:bold;">def</span> absolute_media_uri<span style="color: black;">&#40;</span>media<span style="color: #66cc66;">,</span> request<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> request.<span style="color: black;">build_absolute_uri</span><span style="color: black;">&#40;</span>reverse<span style="color: black;">&#40;</span><span style="color: #483d8b;">'media'</span><span style="color: #66cc66;">,</span> args<span style="color: #66cc66;">=</span><span style="color: black;">&#91;</span><span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span>media<span style="color: black;">&#41;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>Don&#8217;t forget to add a blank <code class="codecolorer text default"><span class="text">__init__.py</span></code> in <code class="codecolorer text default"><span class="text">templatetags/</span></code> or django won&#8217;t take your template tag into account.</p>
]]></content:encoded>
			<wfw:commentRss>http://lois.di-qual.net/blog/django-absolute-media-uris-from-templates/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Un PDF à l&#8217;image de votre CV en ligne avec wkpdf</title>
		<link>http://lois.di-qual.net/blog/un-pdf-a-limage-de-votre-cv-en-ligne/</link>
		<comments>http://lois.di-qual.net/blog/un-pdf-a-limage-de-votre-cv-en-ligne/#comments</comments>
		<pubDate>Thu, 31 May 2012 22:32:46 +0000</pubDate>
		<dc:creator>Loïs Di Qual</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[astuce]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[CV]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[wkpdf]]></category>

		<guid isPermaLink="false">http://127.0.0.1/ldiqual/blog/?p=14</guid>
		<description><![CDATA[Tout comme il est intéressant pour un employeur d&#8217;avoir accès au CV en ligne d&#8217;une potentielle nouvelle recrue, il est également pratique de pouvoir imprimer ce CV dans un format qui convient. La génération automatique d&#8217;un PDF associé au contenu de votre site présente plusieurs avantages: Le PDF est constamment à jour du contenu de [...]]]></description>
				<content:encoded><![CDATA[<p>Tout comme il est intéressant pour un employeur d&#8217;avoir accès au CV en ligne d&#8217;une potentielle nouvelle recrue, il est également pratique de pouvoir imprimer ce CV dans un format qui convient.</p>
<p>La génération automatique d&#8217;un PDF associé au contenu de votre site présente plusieurs avantages:</p>
<ul>
<li>Le PDF est constamment à jour du contenu de votre site</li>
<li>Le PDF adopte le design de votre site</li>
<li>C&#8217;est totalement la classe</li>
</ul>
<p>Voici donc un petit aperçu hautement égocentré de ce que vous pourrez faire:</p>
<p><a href="http://lois.di-qual.net/blog/wp-content/uploads/2012/05/cv_online.png"><img class="alignnone size-medium wp-image-55" title="CV - version en ligne" src="http://lois.di-qual.net/blog/wp-content/uploads/2012/05/cv_online-280x300.png" alt="" width="280" height="300" /></a>       <a href="http://lois.di-qual.net/blog/wp-content/uploads/2012/05/cv_pdf.png"><img class="alignnone size-medium wp-image-56" title="CV - Version PDF" src="http://lois.di-qual.net/blog/wp-content/uploads/2012/05/cv_pdf-300x290.png" alt="" width="300" height="290" /></a></p>
<p>Comme vous l&#8217;aurez remarqué, divers détails graphiques comme l&#8217;arrière-plan gris ou le ruban bleu ont été effacés afin de proposer une version épurée prête à l&#8217;impression.</p>
<p>Pour parvenir à ce résultat, nous allons utiliser un petit logiciel nommé wkpdf associé à une feuille de style spéciale.</p>
<h2>La feuille de style</h2>
<p>Depuis la <a href="http://www.w3.org/TR/html4/present/styles.html#h-14.2.4">version 4 de la norme HTML</a>, il est possible d&#8217;inclure une feuille de style en précisant le type de périphérique auquel elle est adressée. On peut ainsi inclure une une feuille de style spécifique aux télévisions:</p>
<div class="codecolorer-container html4strict twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/link.html"><span style="color: #000000; font-weight: bold;">link</span></a> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">media</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;tv&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;css/tv.css&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></div></td></tr></tbody></table></div>
<p>Il est même possible depuis la version 2 de la norme CSS de déclarer des règles spécifiques à un media directement dans votre feuille de style principale:</p>
<div class="codecolorer-container css twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="css codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">/* Avec @import */</span><br />
<span style="color: #a1a100;">@import url(&quot;tv.css&quot;) tv;</span><br />
<br />
<span style="color: #808080; font-style: italic;">/* Ou avec @media */</span><br />
<span style="color: #a1a100;">@media print {</span><br />
&nbsp; <span style="color: #808080; font-style: italic;">/* Règles spécifiques */</span><br />
<span style="color: #00AA00;">&#125;</span></div></td></tr></tbody></table></div>
<p>Voici la <a href="http://www.w3.org/TR/CSS2/media.html">liste des valeurs</a> de l&#8217;attribut media:</p>
<pre>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">all &nbsp; &nbsp; &nbsp; &nbsp; Suitable for all devices.<br />
braille &nbsp; &nbsp; Intended for braille tactile feedback devices.<br />
embossed &nbsp; &nbsp;Intended for paged braille printers.<br />
handheld &nbsp; &nbsp;Intended for handheld devices (typically small screen, limited bandwidth).<br />
print &nbsp; &nbsp; &nbsp; Intended for paged material and for documents viewed on screen in print preview mode.<br />
projection &nbsp;Intended for projected presentations, for example projectors.<br />
screen &nbsp; &nbsp; &nbsp;Intended primarily for color computer screens.<br />
speech &nbsp; &nbsp; &nbsp;Intended for speech synthesizers.<br />
tty &nbsp; &nbsp; &nbsp; &nbsp; Intended for media using a fixed-pitch character grid (such as teletypes, terminals, or portable devices with limited display capabilities). <br />
tv &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Intended for television-type devices (low resolution, color, limited-scrollability screens, sound available).</div></td></tr></tbody></table></div>

</pre>
<p>Il est à noter que si vous ne précisez pas de media, la valeur de l&#8217;attribut est &#8220;all&#8221; (pour tous les périphériques).<br />
Nous voyons ici que la valeur &#8220;print&#8221; permet de personnaliser un document destiné à être imprimé, c&#8217;est donc celui-ci que nous allons utiliser:</p>
<div class="codecolorer-container html4strict twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/link.html"><span style="color: #000000; font-weight: bold;">link</span></a> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">media</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;print&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;css/print.css&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></div></td></tr></tbody></table></div>
<p>Dans cette feuille de style, supprimons tout ce qui n&#8217;est plus nécessaire, par exemple:</p>
<div class="codecolorer-container css twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="css codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">/* Suppression d'un élément inutile */</span><br />
<span style="color: #6666ff;">.classe-de-l-element</span> <span style="color: #00AA00;">&#123;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">display</span><span style="color: #00AA00;">:</span><span style="color: #993333;">none</span><span style="color: #00AA00;">;</span><br />
<span style="color: #00AA00;">&#125;</span><br />
<br />
<span style="color: #808080; font-style: italic;">/* Suppression de l'arrière plan */</span><br />
body <span style="color: #00AA00;">&#123;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span><br />
<span style="color: #00AA00;">&#125;</span></div></td></tr></tbody></table></div>
<p>Vous pouvez tester ces nouvelles règles en modifiant temporairement l&#8217;attribut media de &#8220;print&#8221; à &#8220;all&#8221;.</p>
<h2>Génération du PDF</h2>
<p>Nous allons utiliser <a href="http://plessl.github.com/wkpdf/">wkpdf</a> pour générer notre fichier. Malheureusement ce dernier n&#8217;est disponible que sur Mac, mais il existe une alternative multiplateforme, <a href="http://code.google.com/p/wkhtmltopdf/">wkhtmltopdf</a>, qui semble fonctionner sur le même principe.</p>
<p>Ces logiciel a un énorme avantage: au lieu de posséder son propre moteur d&#8217;interprétation de la structure HTML, il utilise le fameux Webkit (le moteur de rendu de Chrome et Safari, notamment). Le rendu sera donc fidèle à ce que vous pourrez voir dans un navigateur web conventionnel.</p>
<p>Il vous suffit donc d&#8217;exécuter wkpdf en ligne de commande:</p>
<pre>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ wkpdf --source http://monsite.com/ --output cv.pdf --margins 0 --stylesheet-media print --print-background</div></td></tr></tbody></table></div>

</pre>
<p>De plus, si votre site met en place des éléments graphiques à l&#8217;aide de Javascript, ajoutez les arguments suivants:</p>
<pre>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">--enable-javascript --save-delay [temps_avant_capture_en_secondes]</div></td></tr></tbody></table></div>

</pre>
<p>Vous devriez ainsi obtenir un beau PDF prêt à l&#8217;emploi. Il vous faudra sûrement adapter certaines règles CSS pour que tout tienne sur une page, etc&#8230;</p>
<h2>Bonus: impression directe à partir du site</h2>
<p>La feuille de style &#8220;media=print&#8221; sert également à votre navigateur lors de l&#8217;impression d&#8217;une page. Néanmoins, certaines limitations sont mises en place par la plupart des navigateurs:</p>
<ul>
<li>Les arrières-plans ne sont pas pris en compte. <code class="codecolorer text default"><span class="text">background-color</span></code> et <code class="codecolorer text default"><span class="text">background-image</span></code> ne fonctionneront donc pas.</li>
<li>Le Javascript n&#8217;est pas pris en charge, aucune modification ne pourra être faite dynamiquement avant l&#8217;impression.</li>
</ul>
<blockquote><p>
Note concernant le comportement des navigateurs lors de l&#8217;impression:</p>
<ul>
<li>Aucune référence ou documentation n&#8217;est disponible à ce sujet, du moins pour le moment</li>
<li>Dans certaines versions de Firefox, et sous certains systèmes d&#8217;exploitation, il est possible d&#8217;activer la prise en charge des arrière-plans (couleur et image) ainsi que le Javascript. Là encore, aucune documentation.</li>
<li>Internet Explorer propose un event <code class="codecolorer text default"><span class="text">onbeforeprint</span></code> permettant de modifier le DOM lorsque le navigateur s&#8217;apprête à imprimer. Plus d&#8217;informations <a href="http://msdn.microsoft.com/en-us/library/ie/ms536906(v=vs.85).aspx">par ici</a>.</li>
</ul>
<p>Si vous avez des renseignements supplémentaires concernant les différents comportements adoptés par les navigateurs, n&#8217;hésitez pas à m&#8217;en informer !
</p></blockquote>
<p>Toute l&#8217;astuce consistera donc à remplacer les arrières plans par des images (qui elles seront affichées), ou de tenter de mettre en place une sorte de &#8220;graceful degradation&#8221; afin de simuler certains éléments graphiques. Par exemple, les barres de compétences mises en place sur mon CV ne sont pas pleines lors de leur impression, j&#8217;ai donc dû ajouter un <code class="codecolorer text default"><span class="text">border-color</span></code> pour symboliser les limites de ces dernières.</p>
<h2>Et après ?</h2>
<p>On peut maintenant aisément imaginer un système qui génèrerait automatiquement votre PDF à chaque modification du site web. Si vous utilisez un système de versioning, aucun soucis. Je vous invite à chercher du côté de <code class="codecolorer text default"><span class="text">pre-commit</span></code> si vous gérez tout ça avec svn ou git. Il vous suffira de modifier ces hooks en insérant la commande de génération, et d&#8217;ajouter au commit le fichier PDF ainsi généré.</p>
]]></content:encoded>
			<wfw:commentRss>http://lois.di-qual.net/blog/un-pdf-a-limage-de-votre-cv-en-ligne/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
