<?xml version="1.0" encoding="utf-8"?>
<!-- generator="Kirby" -->
<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">

  <channel>
    <title>Mot-cl&#233;: webdev &#183; Blog &#183; Liip</title>
    <link>https://www.liip.ch/fr/blog/tags/webdev</link>
    <generator>Kirby</generator>
    <lastBuildDate>Tue, 29 May 2018 00:00:00 +0200</lastBuildDate>
    <atom:link href="https://www.liip.ch" rel="self" type="application/rss+xml" />

        <description>Articles du blog Liip avec le mot-cl&#233; &#8220;webdev&#8221;</description>
    
        <language>fr</language>
    
        <item>
      <title>The role of CKAN in our Open Data Projects</title>
      <link>https://www.liip.ch/fr/blog/the-role-of-ckan-in-our-open-data-projects</link>
      <guid>https://www.liip.ch/fr/blog/the-role-of-ckan-in-our-open-data-projects</guid>
      <pubDate>Tue, 29 May 2018 00:00:00 +0200</pubDate>
      <description><![CDATA[<h2>CKAN's Main Goal and Key Features</h2>
<p><a href="https://ckan.org/">CKAN</a> is an open source management system whose main goal is to provide a managed data-catalog-system for Open Data. It is mainly used by public institutions and governments. At Liip we use CKAN to mainly help governments to provide their data-catalog and publish data in an accessible fashion to the public. Part of our work is supporting data owners to get their data published in the required data-format. We’re doing this by providing interfaces and useable standards to enhance the user experience on the portal to make it easier to access, read and process the data.</p>
<figure><img src="https://liip.rokka.io/www_inarticle/2ea997/bookcase.jpg" alt="bookcase"></figure>
<h3>Metadata-Catalog</h3>
<p>Out of the box CKAN can be used to publish and manage different types of datasets. They can be clustered by organizations and topics. Each dataset can contain resources which themself consist of Files of different formats or links to other Data-Sources. The metadata-standard can be configured to represent the standard you need but the Plugin already includes a simple and useful Meta-Data-Standard that already can get you started. The data is saved into a Postgres-Database by default and is indexed using SOLR.</p>
<h3>Powerful Action-API</h3>
<p>CKAN ships with an <a href="http://docs.ckan.org/en/latest/api/index.html">API</a> which can be used to browse through the metadata-catalog and create advanced queries on the metadata. With authorization the API can also be used to add, import and update data with straight-forward requests. </p>
<h3>Cli-Commands</h3>
<p>The standard also includes a range of Cli-Commands which can be used to process or execute different tasks. Those can be very useful, e.g. to manage, automate or schedule backend-jobs.</p>
<h3>Preview</h3>
<p>CKAN offers the functionality to configure a preview of a number of different file-types, such as tabular-data (e.g. CSV, XLS), Text-Data (e.g. TXT), Images or PDFs. That way interested citizens can get a quick overview into the data itself without having to download it first and having to use local Software to merely get an better idea on how the data looks.</p>
<figure><img src="https://liip.rokka.io/www_inarticle/16fb9f/statistik-stadt-zurich-preview.png" alt="Preview von Daten auf Statistik Stadt Zürich"></figure>
<h2>Plugins</h2>
<p>While CKAN itself acts as a CMS but for data, it really shines when making use of its extensibility and configure and develop it to your business needs and requirements. There is already a wide-ranging  list of plugins that have been developed for CKAN, which covers a broad range of additional features or make it easier to adjust CKAN to fit your use cases and look and feel. A collection of most of the plugins can be found on <a href="http://extensions.ckan.org/">CKAN-Extensions</a> and on <a href="https://github.com/topics/ckanext">Github</a>.</p>
<p>At Liip we also help maintaining a couple of CKAN's plugins. The most important ones that we use in production for our customers are:</p>
<h3>ckanext-harvest</h3>
<p>The ckanext-harvest-plugin offers the possibility to export and import data. First of all, it enables you to exchange data between Portals that both use CKAN.</p>
<p>Furthermore we use this plugin to harvest data in a regular manner from different data-sources. At <a href="https://opendata.swiss">opendata.swiss</a> we use two different types of harvesters. Our DCAT-Harvester consumes XML-/RDF-endpoints in <a href="https://handbook.opendata.swiss/en/library/ch-dcat-ap">DCAT-AP Switzerland</a>-Format which is enforced on the Swiss Portal.</p>
<p>The Geocat-Harvester consumes data from <a href="https://geocat.ch">geocat.ch</a>. As the data from geocat is in ISO-19139_che-Format (Swiss version of ISO-19139) the harvester converts the data to the DCAT-AP Switzerland format and imports it.</p>
<p>Another feature of this plugin we use, is our <a href="http://opendata.swiss/catalog.xml">DCAT-AP endpoint</a>, to allow other portals to harvest our data and also serves as an example to Organizations that want to build an export that can be harvested by us.</p>
<figure><img src="https://liip.rokka.io/www_inarticle/02f3fc/harvesting.png" alt="How our Harvesters interact with the different Portals"></figure>
<h3>ckanext-datastore</h3>
<p>The plugin ckanext-datastore stores the actual tabular data (opposing to 'just' the meta-data) in a seperate database. With it, we are able to offer an easy to use API on top of the CKAN-Standard-API to query the data and process it further. It provides basic functionalities on the resource-detail-page to display the data in simple graphs. </p>
<p>The datastore is the most interesting one for Data-Analysts, who want to build apps based on the data, or analyze the data on a deeper level. This is an <a href="https://data.stadt-zuerich.ch/api/3/action/package_show?id=freibad">API-example of the Freibäder-dataset</a> on the portal of <a href="https://data.stadt-zuerich.ch">Statistik Stadt Zürich</a>.</p>
<h3>ckanext-showcase</h3>
<p>We use ckanext-showcase to provide a platform for Data-Analysts by displaying what has been built, based on the data the portal is offering. There you can find a good overview on how the data can be viewed in meaningful ways as statistics or used as sources in narrated videos or even in apps for an easier everyday life. For example you can browse through the <a href="https://data.stadt-zuerich.ch/showcase">Showcases on the Portal of the City of Zurich</a>.</p>
<h3>ckanext-xloader</h3>
<p>The ckanext-xloader is a fairly new plugin which we were able to adopt for the City of Zurich Portal. It enables us to automatically and asynchronously load data into the datastore to have the data available after it has been harvested.</p>
<h2>CKAN Community</h2>
<p>The CKAN-Core and also a number of its major plugins are maintained by the CKAN-Core-Team. The  developers are spread around the globe, working partly in companies that run their own open-data portals. The community that contribute to CKAN and its Plugins is always open to developers that would like to help with suggestions, report issues or provide Pull-Requests on Github. It offers a strong community which helps beginners, no matter their background. The <a href="https://lists.okfn.org/mailman/listinfo/ckan-dev">ckan-dev-Mailing-List</a> provides help in developing CKAN and is the platform for discussions and ideas about CKAN, too.</p>
<h2>Roadmap and most recent Features</h2>
<p>Since the Major-Release 2.7 CKAN requires Redis to use a new system of asynchronous background jobs. This helps CKAN to be more performant and reliable. Just a few weeks ago the new Major-Release 2.8 was released. A lot of work on this release went into driving CKAN forward by updating to a newer Version of Bootstrap and also deprecating old features that were holding back CKAN's progress. </p>
<p>Another rather new feature is the datatables-feature for tabular data. Its intention is to help the data-owner to describe the actual data in more detail by describing the values and how they gathered or calculated.</p>
<p>In the Roadmap of CKAN are many interesting features ahead. One example is the development of the CKAN Data Explorer which is a base component of CKAN. It allows to converge data from any dataset in the DataStore of a CKAN instance to analyze it.</p>
<h2>Conclusion</h2>
<p>It is important to us to support the Open Data Movement as we see value in publishing governmental data to the public. CKAN helps us to support this cause by working with several Organizations to publish their data and consult our customers while we develop and improve their portals together.</p>
<p>Personally, I am happy to be a part of the CKAN-Community which has always been very helpful and supportive. The cause to help different Organizations to make their data public to the people and the respectful CKAN-Community make it a lot of fun to contribute to the code and also the community.</p>
<figure><img src="https://liip.rokka.io/www_inarticle/6a421d/opendata-swiss-homepage.png" alt="Open Data auf opendata.swiss"></figure>]]></description>
                  <enclosure url="http://liip.rokka.io/www_card_2/f90764/account-black-and-white-business-209137.jpg" length="3167986" type="image/jpeg" />
          </item>
        <item>
      <title>5 things you should know about responsive images</title>
      <link>https://www.liip.ch/fr/blog/things-you-should-know-about-responsive-images</link>
      <guid>https://www.liip.ch/fr/blog/things-you-should-know-about-responsive-images</guid>
      <pubDate>Thu, 25 Jan 2018 00:00:00 +0100</pubDate>
      <description><![CDATA[<p>Over the last few years I had to optimize images with <code>srcset</code> on different websites, several times.</p>
<p>After each optimization I thought that I understood how the <code>srcset</code> and <code>sizes</code> attributes of the <code>&lt;img&gt;</code> tag works. But each time, I made some new findings about how these attributes really work and where I need to take care while implementing them. Since there are lots of things you should know before using <code>srcset</code> I thought it could be useful to summarize the most tricky parts in a blog post.</p>
<h2>A short introduction</h2>
<p>I think most of you already heard of responsive images and especially the <code>srcset</code> attribute. But to be on the same page I still would like to start with a short introduction about these two attributes:</p>
<h3>srcset</h3>
<p>The <code>srcset</code> attribute is listing different resolutions of the same image from which the browser chooses the best fitting image source before loading it.</p>
<p>Example: <code>srcset="ninja-1000w.jpg 1000w, ninja-500w.jpg 500w, ..."</code></p>
<p>To calculate this, the browser assumes the image fills up the full viewport width (<code>100vw</code>) by default, which means it uses the full width of the browser.</p>
<h3>sizes</h3>
<p>To tell the browser how much space the image really needs on our viewport, we can use the <code>sizes</code> attribute. This attribute contains a comma separated list of one or more image widths for different viewport sizes.</p>
<p>Each entry is a combination of a <code>media condition</code> and a <code>width</code>. Both of these values are described in <a href="https://webplatform.github.io/docs/tutorials/understanding-css-units/">CSS pixels</a> so we don't need to care about device pixel ratio for this. If the media condition is omitted it evaluates to true automatically (= fallback). The sizes attribute gets read from left to right. As soon as a media condition evaluates to true the width of this entry is used. So be sure to order your values correctly!</p>
<p>Example: <code>sizes="(min-width: 1000px) 50vw, 100vw"</code></p>
<p>The example above tells the browser that if the viewport is at least <code>1000px</code> wide the image fills 50% of the space. If the browser is smaller, the image uses 100% of the available width.</p>
<p>If we combine the above two examples in an <code>&lt;img&gt;</code> tag and request it with a (1x/non-retina) browser the result would be the following:</p>
<ul>
<li>Browser width: <code>500px</code> -&gt; Matching sizes width: <code>100vw</code> -&gt; Needed image size: <code>500w</code> -&gt; Chosen image: <code>ninja-500w.jpg</code>.</li>
<li>Browser width: <code>900px</code> -&gt; Matching sizes width: <code>100vw</code> -&gt; Needed image size: <code>900w</code> -&gt; Chosen image: <code>ninja-1000w.jpg</code>.</li>
<li>Browser width: <code>1000px</code> -&gt; Matching sizes width: <code>50vw</code> -&gt; Needed image size: <code>500w</code> -&gt; Chosen image: <code>ninja-500w.jpg</code>.</li>
</ul>
<h2>Sizes affect how the image is shown</h2>
<p>The first thing which is important to know about the <code>sizes</code> attribute is that it isn't only used to calculate the needed size, it is used as the rendered width of the image if the <code>width</code> is not defined in CSS too.</p>
<p>This means as soon as you add the <code>srcset</code> attribute to the <code>&lt;img&gt;</code> element the image might be displayed differently.</p>
<p>The reason for that is when you add the <code>srcset</code> attribute and omit the <code>sizes</code> attribute, the browser uses the default value for it, which is <code>100vw</code>.</p>
<p>Here's an example (<a href="https://codepen.io/tschortsch/pen/LeMmyO">https://codepen.io/tschortsch/pen/LeMmyO</a>):</p>
<iframe height="370" scrolling="no" title="srcset Example #1" src="//codepen.io/tschortsch/embed/LeMmyO/?height=370&amp;theme-id=0&amp;default-tab=result&amp;embed-version=2" frameborder="no" allowtransparency="true" allowfullscreen="true" style="width: 100%;">See the Pen <a href="https://codepen.io/tschortsch/pen/LeMmyO/">srcset Example #1</a> by Jürg Hunziker (<a href="https://codepen.io/tschortsch">@tschortsch</a>) on <a href="https://codepen.io">CodePen</a>.
</iframe>
<p>As you can see, the browser stretches the image always to the matching size in the sizes attribute, as long as the <code>width</code> is not defined in CSS.</p>
<p>This leads us to <strong>Rule #1: Always set the <code>sizes</code> attribute if you use <code>srcset</code>. If <code>sizes</code> is omitted it defaults to <code>100vw</code>.</strong></p>
<h2>How the browser selects the needed image size</h2>
<p>Short answer: <strong>We can't tell</strong>.</p>
<p>Long answer: Every browser has a slightly different implementation which can change with every version of the browser. This leads to <strong>Rule #2: Never assume which image size the browser will choose</strong>.</p>
<p>The browser just chooses the best matching image for the current size. But if the browser finds a cached version of an image from the current <code>srcset</code> which is bigger than the needed size it prioritizes the image from the cache for example.</p>
<p>This makes it really hard to debug a <code>srcset</code>. To avoid the loading of cached files you should always debug <code>srcset</code>s in your browsers privacy mode.</p>
<p>As a result of this, it is possible that you have two exact same devices (same screen and browser size) but you get a different image size in both browsers.</p>
<p>Another really important takeaway from this brings us to <strong>Rule #3: A <code>srcset</code> should only contain images of the same ratio</strong>.</p>
<p>Since you can't really decide which image is loaded in which browser size you can't use <code>srcset</code> to serve different images on different sizes a.k.a. art direction (eg. 1:1 image on smaller devices, 2:1 image on larger devices). If you would like to do this you should use the <code>&lt;picture&gt;</code> element.</p>
<h2>Pitfalls of the width ('w') descriptor</h2>
<p>The width (<code>w</code>) descriptor of the <code>srcset</code> attribute has also some things which should be taken care of. First of all <strong>Rule #4: The width (<code>w</code>) descriptor should always match the images natural width</strong>. This means if the image has a width of 500px the width (<code>w</code>) descriptor should be exactly <code>500w</code>. This sounds pretty easy to achieve but there are use cases where this isn't as easy.</p>
<p>Think of the following example: You load your images through a CDN, where you predefine all the sizes that should exist of an uploaded image. In the template you define a <code>srcset</code> with all of those predefined sizes. If you do not enable upscaling (on CDN side) and upload an image which is smaller than the biggest defined size, you will get an image which doesn't fit the width (<code>w</code>) descriptor in your template.</p>
<p>If this is the case you can get unexpected results. Let's look at this example (<a href="https://codepen.io/tschortsch/pen/rpoXvW">https://codepen.io/tschortsch/pen/rpoXvW</a> / The problem in the example only occurs with screens that have a DPR &gt;= 2):</p>
<iframe height="370" scrolling="no" title="srcset Example #2" src="//codepen.io/tschortsch/embed/rpoXvW/?height=265&amp;theme-id=0&amp;default-tab=result&amp;embed-version=2" frameborder="no" allowtransparency="true" allowfullscreen="true" style="width: 100%;">See the Pen <a href="https://codepen.io/tschortsch/pen/rpoXvW/">srcset Example #2</a> by Jürg Hunziker (<a href="https://codepen.io/tschortsch">@tschortsch</a>) on <a href="https://codepen.io">CodePen</a>.
</iframe>
<p>If you don't have a display that has a DPR &gt;= 2 here's a screenshot of what would happen if you had:</p>
<figure><img src="https://liip.rokka.io/www_inarticle/edff4e/srcset-example-2-result.jpg" alt=""><figcaption>srcset with wrong size descriptor</figcaption></figure>
<p>What is showed in the example above? As long as we don't define a CSS width, the image (which is originally 400px wide) doesn't fill up a container which is only 300px wide.</p>
<p>Let me explain what's happening here: We have an image container which is 300px wide. The image has a <code>srcset</code> with two possible image sizes: 300w, 600w. The <code>300w</code> image has a natural width of <code>300px</code> (correct). But since the original image has a width of <code>400px</code> the <code>600w</code> doesn't return an image which is <code>600px</code> wide but the original <code>400px</code> image (wrong).</p>
<p>If this container gets loaded with a DPR &gt;= 2 the browser requests the <code>600w</code> image (2 * 300px). Since the browser doesn't know that the image behind this descriptor is smaller than <code>600px</code> it displays it as it would be that size. This means it gets squeezed to half of its size (400px / 2 = 200px). And that's why we end up with this strange situation that the image (which is originally 400px wide) doesn't fill the whole 300px image container.</p>
<p>When we enforce the image width in CSS, like we do in the 2nd example, the (400px) image gets stretched again to fill the 300px container and everything looks like expected.</p>
<p>And here we are with the <strong>Rule #5: Always enforce the image size in CSS when using <code>srcset</code></strong>.</p>
<h2>Wrap up</h2>
<p>As you see responsive images have some parts, you should know when implementing them. Let's quickly go through our rules again:</p>
<ul>
<li><strong>Rule #1: Always set the <code>sizes</code> attribute if you use <code>srcset</code>. If <code>sizes</code> is omitted it defaults to <code>100vw</code>.</strong> Since the <code>sizes</code> attribute has an influence on how the image is displayed, it should never be omitted. If you do so, the browser uses the default value of <code>100vw</code>.</li>
<li><strong>Rule #2: Never assume which image size the browser will choose</strong>. The reason for this is, that all browsers have slightly different implementation on how the correct image from a <code>srcset</code> is chosen. This implementation should be a black box for us, because it can change with every update.</li>
<li><strong>Rule #3: A <code>srcset</code> should only contain images of the same ratio</strong>. As a result of rule #2 we never know which image is loaded by the browser. To get the same result for all visitors every image in the <code>srcset</code> needs the same ratio.</li>
<li><strong>Rule #4: The width (<code>w</code>) descriptor should always match the images real width</strong>. The browser uses the width (<code>w</code>) descriptor to calculate how it should display the image. If it doesn't match the real width, we can get unexpected behaviour.</li>
<li><strong>Rule #5: Always enforce the image size in CSS when using <code>srcset</code></strong>. Since there are some use cases where rule #4 can't be achieved, we should always enforce the width of an image in CSS.</li>
</ul>
<h2>Further resources</h2>
<p>There are some really good resources to learn more about responsive images:</p>
<ul>
<li>Responsive images on Mozilla Developer Network: <a href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images">https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images</a></li>
<li>Responsive images on CSS-Tricks: <a href="https://css-tricks.com/responsive-images-youre-just-changing-resolutions-use-srcset/">https://css-tricks.com/responsive-images-youre-just-changing-resolutions-use-srcset/</a></li>
<li>Very nicely done introduction about <code>srcset</code> and <code>sizes</code>: <a href="http://ericportis.com/posts/2014/srcset-sizes/">http://ericportis.com/posts/2014/srcset-sizes/</a></li>
<li><code>&lt;img&gt;</code> Element documentation: <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img">https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img</a></li>
</ul>]]></description>
                  <enclosure url="http://liip.rokka.io/www_card_2/f1f97c/tablet-8-digital.jpg" length="1704799" type="image/jpeg" />
          </item>
        <item>
      <title>OctoberCMS&#8230; or why do we need yet another CMS?</title>
      <link>https://www.liip.ch/fr/blog/octobercms-or-why-do-we-need-yet-another-cms</link>
      <guid>https://www.liip.ch/fr/blog/octobercms-or-why-do-we-need-yet-another-cms</guid>
      <pubDate>Wed, 24 Jan 2018 00:00:00 +0100</pubDate>
      <description><![CDATA[<p>Over the last few years we created lots of projects with WordPress and it was - and still is - a pleasure to do so. But we had some requests where WordPress just didn't exactly fit. WordPress is great when it comes to basic websites. But as soon as you have requirements which are more complex or you even need to create a web application, WordPress isn't the right choice probably.</p>
<h2>What is OctoberCMS?</h2>
<p>WordPress is based on simplicity - everything is a post, which makes it easy to use for content authors and developers. Thanks to this concept, (nearly) all backend forms look consistent which helps content authors a lot. But this simplicity makes it harder for developers to create backends for more complex content.</p>
<p>This is where OctoberCMS jumps in. It is a great mix of a file based and database driven CMS. Everything which is more or less static (like pages, menus and templates) is saved as files. Like this the content can be served really fast. However you can of course edit these entities directly through the backend.</p>
<p>Everything which is more dynamic and more complex (like events, news or blogposts) is stored in custom tables in the database. Thanks to this you will have full freedom on how to create your own types.</p>
<h2>Complexity doesn't matter</h2>
<p>With this strategy OctoberCMS can be used for simple websites as well as for really complex ones. When using it for simple websites, the user experience of the backend can be compared to the one of WordPress. It is easy to use and looks consistent. On top of that it adds some useful features for power users, like editing multiple content elements in tabs or keyboard shortcut. The most useful one is saving data with <kbd>CMD+S</kbd> / <kbd>CTRL+S</kbd>. I'm already at a point where I find myself trying to save blogposts in WordPress with this key combination (which doesn't work sadly).</p>
<p>When using it for a more complex website you'll get full freedom on what to use OctoberCMS for. You can easily use it as a headless CMS for any sort of web application. To help you with this, the backend gives you a base structure for list views and form views for each model. If required you can modify these templates to fit your own needs. The provided form widgets helps creating consistent backend forms for almost every use case. If needed you can create your own form widgets without any hassle. This means the backend is highly customizable which improves the usability when editing complex content extremely.</p>
<h2>Still not convinced?</h2>
<p>Let's look at some more, great reasons why you should consider OctoberCMS for your next website:</p>
<ul>
<li><strong>Based on Laravel:</strong> OctoberCMS is based on the <a href="https://laravel.com/">Laravel framework</a> (which is based on Symfony. It builds a really solid foundation for the core, plugins and themes.</li>
<li><strong>Clean code:</strong> By using the Laravel framework there is clear <a href="https://laravel.com/docs/5.5/contributions#coding-style">coding style definition</a> which helps your code base to stay clean.</li>
<li><strong>Open Source:</strong> The whole OctoberCMS project is hosted as open source software on <a href="https://github.com/octobercms/october">GitHub</a> which is a really important thing to build a big user community around.</li>
<li><strong>Easy to extend:</strong> OctoberCMS is built for extensibility. The best example for that is that even the most basic features, like creating and editing pages, are provided via a <a href="https://github.com/rainlab/pages-plugin">plugin</a> and are not hardcoded in the core.</li>
<li><strong>Database query building with Eloquent:</strong> For database query building Laravel has <a href="https://laravel.com/docs/5.5/eloquent">Eloquent ORM</a> integrated. With this you can easily create database queries which fits your needs.</li>
<li><strong>Database migrations:</strong> The whole OctoberCMS setup (core and plugins) is based on <a href="https://octobercms.com/docs/database/structure#migration-structure">database migrations</a>. This helps keeping the database consistent when installing or updating plugins or the core. With this mechanism you can easily rollback to an older version if something doesn't work as expected.</li>
<li><strong>Event driven:</strong> The whole setup is <a href="https://octobercms.com/docs/services/events">event driven</a> which enables you hook into core or plugin processes and extend them easily.</li>
<li><strong>Twig templates:</strong> OctoberCMS uses <a href="https://octobercms.com/docs/markup/templating">twig as templating engine</a>. This makes it possible to completely separate your data from the templates.</li>
<li><strong>Integrated assets pipeline:</strong> OctoberCMS comes with a twig based <a href="https://octobercms.com/docs/markup/filter-theme">assets pipeline</a> to compile and minify your CSS (support for Sass &amp; Less) and JS files. All you need to do is including your source files directly in your twig templates and they get compiled, minified and cached automatically when calling the website the first time. If you have more complex requirements Laravel provides an abstraction layer above webpack called <a href="https://github.com/JeffreyWay/laravel-mix">Laravel Mix</a> which makes the creating of webpack based build tasks easy.</li>
</ul>
<h2>The bad parts</h2>
<p>Not everything can be nice and shiny. So here we go with the imperfect or missing parts of OctoberCMS:</p>
<h3>Core bugs</h3>
<p>First of all since this is a rather new CMS project (compared to other big players on the market) you might find some more or less &quot;simple&quot; core bugs while implementing a complex backend feature. This can be annoying, but since the community is very active (on <a href="https://octobercms.com/forum/post/octobercms-is-now-on-slack">Slack</a> or on <a href="https://github.com/octobercms/october">GitHub</a>) you will get help quickly.</p>
<h3>i18n</h3>
<p>Another important topic is <strong>i18n</strong>: OctoberCMS provides an implementation for translating content as a <a href="https://github.com/rainlab/translate-plugin">plugin</a>. With it you are able to translate most of your content from a base language to other languages which works fine.</p>
<p>But since you always need your content to exist in a base language you are limited to only translating your website and not doing real i18n stuff like different content in different languages. The good thing about this is that the folks behind this plugin are working on that feature right now and since the <a href="https://github.com/rainlab/translate-plugin">plugin is hosted on GitHub</a> you can help if you want.</p>
<h2>That's all folks</h2>
<p>We're really looking forward to build a lot more websites with OctoberCMS. And if you are a web developer you should really consider it when planning your next CMS project.</p>]]></description>
                  <enclosure url="http://liip.rokka.io/www_card_2/846eca/octobercms.jpg" length="52020" type="image/png" />
          </item>
        <item>
      <title>This site now runs on SPDY</title>
      <link>https://www.liip.ch/fr/blog/this-site-now-runs-on-spdy</link>
      <guid>https://www.liip.ch/fr/blog/this-site-now-runs-on-spdy</guid>
      <pubDate>Thu, 21 Jun 2012 00:00:00 +0200</pubDate>
      <description><![CDATA[<p><a href="http://en.wikipedia.org/wiki/SPDY">SPDY</a>? SPDY is an “upgrade” to HTTP 1.1 <a href="https://developers.google.com/speed/spdy/">proposed by Google</a>to circumvent some of the shortcomings of HTTP 1.1. It's one of the canditates for “ <a href="http://en.wikipedia.org/wiki/HTTP_2.0">HTTP 2.0</a>” and is already supported by Chrome and Firefox. It's goal is to make the web experience faster (and more secure).</p>
<p>The main feature from my point of view is that with SPDY the browser only has to open one TCP connection to the server and all resources are delivered through that connection. No need anymore to “fake” different servers with different hostnames just that the browser fetches more than the default 4 to 6 resources at once from one server. This also saves resources on the server as it also has only to keep one connection open. This especially helps, if you have lots of little resources on your webpage, eg. lots of small images.</p>
<p>SPDY also adds features that a lost package doesn't stop the whole delivery and other requests still can get through fast called multi-plexing (compared to HTTP Pipelining, which is First-In-First-Out) and since everything is going over one TCP connection, SPDY can much better handle congestion and better use the available bandwidth (see also <a href="http://www.brianp.net/2011/07/19/will-http-pipelining-help-a-study-based-on-the-httparchive-org-data-set/">this post for more info</a>)</p>
<p>Furthermore it also compresses the HTTP Headers (something HTTP doesn't by design and can sum up to quite some traffic, especially if you have many small requests)</p>
<p>You don't have to change anything in your websites and web applications to make use of SPDY, only the browser and the webserver have to support it, on the other layers it still works like HTTP.</p>
<p>All this together should especially help on mobile devices, where latency, packet loss and bandwidth still is a problem and any improvements in that area helps a lot in making a more responsive web experience.</p>
<h2>SPDY on this blog</h2>
<p>There was actually no real need for having SPDY on our blog. We don't have that many requests on a single page to the same server and our server isn't really overloaded with open TCP connection (currently it's an AWS micro instance, not the most powerfull machine in the world ;)). But it is a little playground for us to try out new things, get some experience with those and to be able to make an informed decision if we should/could use them in our projects. So I went ahead.</p>
<p>Google provides packages for <a href="https://developers.google.com/speed/spdy/mod_spdy/">Apache SPDY modules</a>, so that was installed fast. But our server was running mod_php5 and that doesn't work very well with mod_spdy (which is somehow obvious, since SPDY just opens one TCP connection for all (parallel) requests, something hard to do with the pre-fork model mod_php5 needs). So I had to move my PHP needs to PHP-FPM and use FastCGI and the Worker MPM of apache. There wasn't anything special I had to do. It's the usual setup of using PHP-FPM with apache (see for example <a href="https://github.com/josegonzalez/homebrew-php/wiki/Develop:-Using-PHP-FPM">here</a>) and since the mod_rewrite rules still work, I didn't even have to change them. After that and installing mod_spdy_beta.deb I basically had a running SPDY site on our SSL port.</p>
<p>This is also one of the issues and main criticisms  about SPDY. It only runs with SSL (currently). That has the advantage that the future HTTP may be secure by default, but also the disadvantage that you need certificates and all that to set it up. This wasn't difficult for this site since we already had SSL running for the admin interface. The next question was how to bring visitors to the SPDY version of the blog. Just send everyone to SSL didn't sound like a good idea, because with “old HTTP” SSL has more overhead in setting up a connection and since you will have many of those connections, that really will be a penalty. One trick is to send the following header to all clients connecting on port 80</p>
<pre><code>Alternate-Protocol: 443:npn-spdy/2</code></pre>
<p>Then SPDY-enabled clients will use SPDY for the upcoming requests. This works fine on Chrome, on Firefox I had the problem that our webfont somehow wasn't loaded and displayed. So I added this to our mod_rewrite rules:</p>
<pre><code>RewriteCond  %{HTTP_USER_AGENT}  Firefox/[0-9]{2}.
RewriteCond  %{SERVER_PORT}  ^80$
RewriteRule ^/*(.*)$ https://blog.liip.ch/$1 [L,R=301]</code></pre>
<p>This redirects all Firefox versions &gt;= 10. to SSL. Not the best solution, since the redirect adds latency, but for the sake of it, it's good enough for me here. I will revisit the webfont issue later, maybe it is indeed a bug in Firefox which will be fixed later.</p>
<p>That was basically it, if you now go to our blog with Chrome or Firefox, you should be served by SPDY. You can check that by installing one of the SPDY indicator plugins ( <a href="https://chrome.google.com/webstore/detail/mpbpobfflnpcgagjijhmgnchggcjblin">Chrome</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/spdy-indicator/">Firefox</a>) or in Chrome go to  <a href="chrome://net-internals/#spdy">chrome://net-internals/#spdy</a> and see which sites you have open use SPDY (twitter and google are 2 major sites already using SPDY).</p>
<p>One thing you have to also keep an eye on is that once you deliver your site in SSL, you should deliver all content over SSL. Otherwise you may get warnings in the browser (I didn't change all the externals URLs in the individual posts on this blog, so you may hit that warning from time to time)</p>
<h2>What about nginx?</h2>
<p>This all could be done also with nginx (apart from our very customized mod_rewrite rules which prevent a totally easy move), but SPDY support was <a href="http://trac.nginx.org/nginx/ticket/30">only published last week</a> and you have to patch and recompile nginx (no binaries yet). Not something I was very keen to do. But support is coming and certainly a standard in the near future.</p>
<h2>Outlook</h2>
<p>I really hope SPDY (or something similar) will gain widespread adoption in the near future. Everything which makes delivering web resources faster, especially on high-latency, packet-lossy and limited-bandwidth environments is worth pursuing and it's obvious that SPDY does solve some problems in that area (if you ever tried to surf the web on a full Swiss train you know what I'm talking about ;))</p>
<p>And with the compiled packages by google it's easy to set it up on your server, provided you use apache, some fastcgi for PHP and have a decent SSL certificate already (many ifs…). If that's the case, why not playing with it and gain some experience.</p>
<p>I also can't wait the day when varnish supports SPDY natively. There are no plans as far as I know and it doesn't look like they're willing to do it soon. But if it gains more widespread adoption, I'm sure they will support it some day. Until then your only way to have SPDY and varnish is to put an nginx/apache in front of varnish. Which solves the problems mentioned above for mobile networks, but not the “too many open connections on the server side” problem. But that's mitigated somehow anyway if you use varnish.</p>
<p>And last but not least, for me as an Apple follower, I can't wait until it's built-in in iOS ;)</p>]]></description>
          </item>
        <item>
      <title>My Fronteers 2010 experience</title>
      <link>https://www.liip.ch/fr/blog/my-fronteers-2010-experience</link>
      <guid>https://www.liip.ch/fr/blog/my-fronteers-2010-experience</guid>
      <pubDate>Wed, 27 Oct 2010 00:00:00 +0200</pubDate>
      <description><![CDATA[<p>Every liiper gets a time and money budget to learn new stuff. The past four years I attended the <a href="http://www.paris-web.fr/">Paris Web conference</a> and came back every year with fresh ideas. But this year I decided it was time for a change. That's how I ended up attending this year's <a href="http://fronteers.nl/congres/2010">Fronteers conference</a> in Amsterdam.</p>
<p>Now that all the <a href="http://vimeo.com/channels/fronteers10">videos of the Fronteers talks are online</a>, I wanted to shared with you what I came back with, so that you also go benefit from this resource.</p>
<h1>The Venue</h1>
<p>I have been to some conferences, but this venue just rocked them all. We were hosted in the <a href="http://en.wikipedia.org/wiki/Tuschinski">Pathé Tuschinski movie theater in the middle of Amsterdam</a>. The <a href="http://www.flickr.com/photos/lejoe/sets/72157624989374041/detail/">pictures I took of this place</a> describe how perfect this place was, much better than I could explain it with words:</p>
<figure><a href="http://www.flickr.com/photos/lejoe/sets/72157624989374041/detail/"><img src="https://liip.rokka.io/www_inarticle/e92b38bb7cc4a74a75b7a6e9022f2cb7f4b0dbbb/tuschinski.jpg" alt="pathe tuschinski in Amsterdam"></a></figure>
<h1>The Lineup</h1>
<p><a href="http://fronteers.nl/congres/2010/speakers">The lineup of speakers</a> was pretty impressive. Paul Irish, Jeremy Keith, Nicholas Zakas, Robert Nyman, Christian Heilmann, Stoyan Stefanov to name some of them. A whole bunch of wise guys. It was a blessing to listen to what they had to share.</p>
<h1>The topics</h1>
<p><strong>CSS3</strong> , <strong>javascript</strong> and of course everything around <strong>HTML5</strong> were the trending topics. Lately, I somehow got an overdose of hearing about HTML5 everywhere again. But those speakers all presented their stuff with their own perspective and that made it really pleasant and inspiring to follow.</p>
<p><a href="http://adactio.com">Jeremy Keith</a>, for example, took us through <a href="http://vimeo.com/15755349"><strong>the design principles on which HTML5 is built</strong></a>. I am still fascinated on the vision behind this standard. I truly believe such principles are what made the current standard a success and what will ensure its future.</p>
<p><a href="http://people.opera.com/howcome/">Håkon Wium Lie</a>, CTO of opera and long time member of the CSS working group went with us through <strong> <a href="http://vimeo.com/15775937">the new features of CSS3</a></strong> . He shared some pictures and anecdotes of the times he spent with Tim Berners Lee in the CERN, about 20 years ago, to illustrate what was inspiring them while creating the concept of CSS.</p>
<p><a href="http://owltastic.com/">Meagan Fisher</a> and <a href="http://sushiandrobots.com/">Jina Bolton</a> gave us their web designer perspective. Meagan showed us <strong> <a href="http://vimeo.com/15991551">how she uses the new CSS3 properties</a></strong> to give even a better look to her designs on browsers that support them. Jina told us about <a href="http://vimeo.com/15982903"><strong>the workflow she goes through while writing CSS</strong></a>.</p>
<p>I'm not a designer, but I envy their talent and creativity. A journey in a mind of such designers was a real gift to me.</p>
<p>I think you got the point and I won't comment <a href="http://fronteers.nl/congres/2010/sessions">every talk</a> as you can find them <a href="http://vimeo.com/channels/fronteers10">online</a>. Let me just recommend three of them to start with.</p>
<h1>The 3 talks you should see</h1>
<h2>“ <a href="http://vimeo.com/15981041">Progressive Downloads and Rendering</a>” by <a href="http://www.phpied.com/">Stoyan Stefanov</a></h2>
<p>If you care at lot about performance for high traffic websites this is the talk to watch. Probably the talk where I learnt the most.</p>
<h2>“ <a href="http://vimeo.com/15984466">Reusable Code, for good or for awesome!</a>” by <a href="http://www.jakearchibald.com">Jake Archibald</a></h2>
<p>Jake talked about how to design an API and making sure it's reusable. He mostly uses javascript as example, but the principles he presents (and which I cherish too) are relevant to any coding environment. The bonus of this talk is how entertaining that guy is.</p>
<h2>“ <a href="http://vimeo.com/16249024">Reasons to be cheerful</a>” by <a href="http://wait-till-i.com/">Chris Heilmann</a></h2>
<p>This is <strong>THE</strong> talk I would recommend to everyone working for the web. For about an hour he tells us why we have one of the most awesome jobs in the world. I enjoyed sitting there and contemplating his speaker talent delivering all the reasons why I do this job.</p>]]></description>
          </item>
        <item>
      <title>Techday Slides: oEmbed</title>
      <link>https://www.liip.ch/fr/blog/techday-slides-oembed</link>
      <guid>https://www.liip.ch/fr/blog/techday-slides-oembed</guid>
      <pubDate>Fri, 16 Jul 2010 00:00:00 +0200</pubDate>
      <description><![CDATA[<p>Bart, one of our newest Liipers, made a talk about <a href="http://www.oembed.com/">oEmbed</a>. Even though the technology exists since quite some time, not many Liipers knew of it. So we all learned something here. <a href="https://www.liip.ch/blog/techday-slides-oembed/20100707_bart_ombed.pdf">Get his slides</a>.</p>]]></description>
          </item>
    
  </channel>
</rss>
