<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2enclosuresfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel xml:lang="fr">
	<title>SPIP</title>
	<link>http://www.spip.net/</link>
	<description>Système de Publication pour Internet</description>
	<language>fr</language>
	<generator>SPIP - www.spip.net</generator>

	<image>
		<title>SPIP</title>
		<url>http://www.spip.net/local/cache-vignettes/L144xH49/siteon0-56029.jpg</url>
		<link>http://www.spip.net/</link>
		<height>49</height>
		<width>144</width>
	</image>



<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Spip" /><feedburner:info uri="spip" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><itunes:explicit>yes</itunes:explicit><itunes:subtitle>Système de Publication pour Internet</itunes:subtitle><item xml:lang="en">
		<title>SPIP 3.0</title>
		<link>http://feedproxy.google.com/~r/Spip/~3/Jnb0ouqE09k/en_article5533.html</link>
		<guid isPermaLink="false">http://www.spip.net/en_article5533.html</guid>
		<dc:date>2012-05-27T10:18:07Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>en</dc:language>
		<dc:creator>George Kandalaft, Paolo</dc:creator>


		<dc:subject>SPIP 3.0</dc:subject>

		<description>
&lt;p&gt;SPIP 3 is a major upgrade. The following features are of special note: the private area has been completely revamped using customisable templates, a high degree of modularity (all non-core functionalities are now in plugins), and a revolutionary DATA loop which allows SPIP to connect to many new kinds of data.&lt;br class='autobr' /&gt;
SPIP 2.0 could already be used as a “framework” for developing Web applications, well beyond SPIP's original purpose as a simple CMS. SPIP 3 pushes the logic of the “framework” further (...)&lt;/p&gt;


-
&lt;a href="http://www.spip.net/en_rubrique247.html" rel="directory"&gt;Upgrades and version history&lt;/a&gt;

/ 
&lt;a href="http://www.spip.net/@spip30" rel="tag"&gt;SPIP 3.0&lt;/a&gt;

		</description>


 <content:encoded><![CDATA[<div class='rss_chapo'><p><strong>SPIP 3</strong> is a major upgrade. The following features are of special note: the private area has been completely revamped using customisable templates, a high degree of modularity (all non-core functionalities are now in plugins), and a revolutionary DATA loop which allows SPIP to connect to many new kinds of data.</p></div>
		<div class='rss_texte'><p><a href="http://www.spip.net/en_article3837.html" class='spip_in' hreflang='en'><span style='color: #273494;'>SPIP 2.0</span></a> could already be used as a “framework” for developing Web applications, well beyond SPIP's original purpose as a simple CMS. <strong>SPIP 3</strong> pushes the logic of the “framework” further so that it can now be applied to SPIP itself: The whole private area of SPIP has been revamped into templates, themselves based on the tools and features offered by SPIP's template language.</p> <p>This rewrite of the private area was an opportunity to rethink all the editorial objects and standardise their use to make them as generic as possible: most of the historical particularities of each object (and associated processing exceptions in SPIP code) have been reduced to a simple declaration.</p> <p>In this way the creation of new editorial objects and the customisation of existing objects have become much easier and quicker.</p> <p><strong>SPIP 3</strong> also concludes the modularisation of the software into plugins which SPIP 2 had begun: all the features offered by SPIP 2 are now based on a core <strong>SPIP 3</strong> accompanied by 23 plugins.</p> <p>This segmentation of the core has made it possible to complete the system of APIs and entry points for plugin developers.</p> <p><strong>SPIP 3</strong> has drawn heavily on developments made by the SPIP-Zone community, and this marks a reversal: it is no longer the core programme which is encouraging the development of plugins, but instead development of plugins which, by their experimentation, is now fuelling the advance of SPIP.<span class="spip_note_ref"> [<a href='#nb1' class='spip_note' rel='footnote' title='Besides The Quill which was already integrated to SPIP 2, this movement (...)' id='nh1'>1</a>]</span>.</p> <p>Among its new functions, <strong>SPIP 3</strong> introduces a new loop, <a href="http://www.spip.net/fr_article5444.html" class='spip_in' hreflang='fr'>DATA</a> which now makes it possible to loop over any kind of data, not only SQL tables. You can now browse an enum or a <a href="http://www.spip.net/fr_article5443.html" class='spip_in' hreflang='fr'>CSV, XML, YAML</a> file. And furthermore, the DATA loop can even be used directly on a URL: thus it becomes possible to directly integrate data from a Google spreadsheet, an <a href="http://www.spip-contrib.net/Plugin-iCalendar" class='spip_out' hreflang='en' rel='external'>online calendar</a>, a list of <a href="http://www.spip.net/fr_article5445.html" class='spip_in' hreflang='fr'>Youtube videos</a>, <a href="http://www.spip.net/fr_article5445.html" class='spip_in' hreflang='fr'>photos on Flickr</a> ... the Web becomes your database if not your oyster!</p> <p><strong>System requirement</strong>:<br class='autobr' />
In order to function correctly, <strong><span style="color:#00CAD8">SPIP 3.0</span></strong> needs PHP version 5.1.0 or newer.</p>
<h3 class="spip">A new private area<span class="spip_note_ref"> [<a href='#nb2' class='spip_note' rel='footnote' title='This project has begun some time ago on SPIP-Zone, and those who have (...)' id='nh2'>2</a>]</span></h3>
<p>Visually, the private area remains in continuity with previous versions, while using new icons:<br />- * the main icons for navigation are a <a href="http://sevcommunication.com/De-nouvelles-icones-pour-SPIP-3" class='spip_out' rel='external'>set made for SPIP by Sebastian Desbenoit</a> <br />- * the other icons are from a set which was derived from FatCow.</p> <p>The revamping of the interface is essentially technical, though it has also solved a number of ergonomic flaws.</p> <p>The navigation system has been redesigned. The drop-down menu, now fully navigable with the keyboard, also integrates delays for ease of use with the mouse and to be more robust against poorly controlled movements.</p> <p>All of the private area is now in the form of templates stored in the <strong><code class='spip_code' dir='ltr'>prive/squelettes</code></strong> directory, organised by subdirectories corresponding to a division of the page into blocks. This division is mainly used for reloading pieces of a page with Ajax, avoiding the full reload of pages and making actions more fluid<span class="spip_note_ref"> [<a href='#nb3' class='spip_note' rel='footnote' title='For example, opening an article for editing becomes instantaneous thanks to (...)' id='nh3'>3</a>]</span>.</p> <p>Many entry points (primarily used by the core plugins) are available as pipelines to allow plugins to extend the functionality of the private area.</p> <p>Pages of the private area have been reorganised and renamed. In particular all pages of editorial objects use a consistent naming scheme based on the object name.</p> <p>The rewrite also allowed for an upgrade of the HTML structure and its accessibility. A programming guide has been set up so that plugin developers can use the same structures, and that the interfaces they add remain consistent with the core.</p> <p>All objects lists are templates, and therefore easy to customize. They all have built-in sorting by column and ajax pagination.</p> <p>A scaffolding system of object pages can automatically build a minimal interface for new objects declared by plugins. Each element of the default interface can then be customized according to the particularities of each object:<span class="spip_note_ref"> [<a href='#nb4' class='spip_note' rel='footnote' id='nh4'>4</a>]</span>.</p> <p>All interactive forms are written as <a href="http://www.spip.net/en_article3980.html" class='spip_in'>CVT forms</a>, which ensures good management of error messages, input checking, ajax robust control, and multi-page forms are available if necessary. They can all be easily extended by plugins.</p> <p>In edit mode SPIP 3 takes carriage returns into account (it is no longer necessary to use “<code class='spip_code' dir='ltr'>_</code>”).</p> <p>Lastly, the private area includes a mechanism for themes, allowing them to customize the style sheets, or some or all of the icons. This mechanism can be used by a plugin offering the user to choose a preferred presentation.</p>
<h3 class="spip">Modularity with plugins</h3>
<p><strong>SPIP 3</strong> has concluded the process of fragmenting the system into plugins. The core retains the management of articles, sections and authors, the template language and the structure of the private area. All other functions are now outsourced in plugins which are automatically installed with the default distribution of <strong>SPIP 3</strong>. These default plugins are storedin the directory <code class='spip_code' dir='ltr'>plugins-dist/</code><span class="spip_note_ref"> [<a href='#nb5' class='spip_note' rel='footnote' title='In SPIP 2.1 they were placed in the which now disappears.' id='nh5'>5</a>]</span></p> <p>This separation of functions has made it possible to define a number of implicit APIs, which are now available to plugin developers who can add functionalities without limit, modelled on SPIP's native plugins.</p> <p>In the field of plugins, <strong>SPIP 3</strong> also brings a major overhaul of the formalism of the XML declaration. Besides improved readability, the question of translations of plugins is treated and there are automatic tools for listing plugins and for loading them.</p> <p>Plugins can also make use of the upgrading functions of the core database (with recovery after timeout) by a simple declaration of the procedure.</p> <p>Plugins distributed with SPIP default are:</p>
<ul class="spip"><li> <strong>Brèves</strong> deals with the editorial object <i>News Items</i>. </li><li> <strong>Companion</strong> displays information and support during the initial access to the private area.</li><li> <strong>Compressor)</strong> (already in SPIP 2.1) optimizes performance by compressing and concatenating CSS and JavaScript files used. This version of the plugin improves sheets by media. Using @media to concatenate all media into one file without changing the load order. Absolute urls are managed without protocol so that compressed style sheets work with both http and https.</li><li> <strong>Dump</strong> manages backup and recovery. The feature has been completely rewritten to provide a full and reliable backup. The backup format is now SQLite and all tables are systematically preserved.</li><li> <strong>Forum</strong> manages the editorial object <i>forum</i>, both for the public site and the private area. In addition to a redesigned moderation interface, forums can now be used on all SPIP objects (whether native or added through plugins).</li><li> <strong>Images</strong> (already in SPIP 2.1) manages all the image and colour filters which can be used in templates.</li><li> <strong>jQueryUI</strong> implements this library in SPIP. It facilitates the creation of dynamic graphical components: tabs, drag & drop, progress bars, widgets, effects ... </li><li> <strong>Mediabox</strong> integrates a default <i>pop-in</i> box to view media or offer interactions<span class="spip_note_ref"> [<a href='#nb6' class='spip_note' rel='footnote' title='This is an alternative, based on the library Colorbox, to plugins such as (...)' id='nh6'>6</a>]</span>.</li><li> <strong>Medias</strong><span class="spip_note_ref"> [<a href='#nb7' class='spip_note' rel='footnote' title='Known in SPIP 2 under the name “Media Library”' id='nh7'>7</a>]</span> manages documents and images. It redesigns the interface and allows documents to be attached to any editorial object. </li><li> <strong>Mots</strong> manages keywords and keyword groups. The keywords can now be used on all editorial objects.</li><li> <strong>Organiseur</strong> provides the messaging functions and internal calendar of the editing area. The interface is completely redesigned. Internal messaging has email notification, and the calendar is based on the library FullCalendar allowing smooth navigation.</li><li> <strong>Pétitions</strong> handles petition items and offers a redesigned moderation interface. </li><li> <strong>Quill (Porte-plume)</strong> (already in SPIP 2.1) provides input assistance.</li><li> <strong>Revisions</strong> provides versioning which can be used on all SPIP editorial objects. The management interface has been updated. </li><li> <strong>SafeHTML</strong> (already in SPIP 2.1) takes care of potentially threatening external content.</li><li> <strong>Sites</strong> makes the “Syndicated sites” object work as well as syndicated articles. An interface to moderate syndicated articles is available.</li><li> <strong>Squelettes par rubriques</strong> (Templates per section) makes templates with suffixes work (article-2.html for articles of section 2 and its sub-sections, etc.). </li><li> <strong>Statistics</strong> provides the calculation of statistics for the sites and articles, with a completely redesigned interface.</li><li> <strong>Support of older browsers</strong> (already in SPIP 2.1) offers JavaScript functions which can be activated to allow older browsers to display your site correctly.</li><li> <strong>SVP</strong> manages plugins: search, installation, activation, update, ... </li><li> <strong>TextWheel</strong> is an engine that supports SPIP's typographical shortcuts. They are now defined in a rule file in YAML format. This results in a significantly quicker calculation of shortcuts (up to twice as fast with some content), and facilitates the development and customization of shortcuts.</li><li> <strong>Urls Etendues</strong> supports contextual URLs or hierarchical URLSs, and provides a configuration interface and an optional advanced management interface to give fine control over the URLs of each page. </li><li> <strong>Vertebrae</strong> (already in SPIP 2.1) allows the webmaster to display the content of a SPIP SQL table using an automatically generated template based on the structure of the SQL table. This display is now in the private area.</li></ul><h3 class="spip">A new set of default templates</h3>
<p>To mark the occasion the default templates have been revised. With the division of styles into various independently reusable stylesheets (<a href="http://romy.tetue.net/817" class='spip_out' rel='external'>see Daisy method</a> and <a href="http://spip-blog.net/703" class='spip_out' rel='external'>One, two, three ... CSS</a>), there is now a modular HTML/CSS basis on which a site can be built straight away. A full, harmonious typographical treatment, based on the Blueprint framework, forms one part of the CSS. The old stylesheet <code class='spip_code' dir='ltr'>spip_style.css</code> gives way to <strong><code class='spip_code' dir='ltr'>spip.css</code></strong>, which can be used as a complement to your usual framework.</p> <p>The templates adopt a new <a href="http://romy.tetue.net/826" class='spip_out' rel='external'>HTML base structure</a> which already put in place some HTML5 elements; they are <a href="http://en.wikipedia.org/wiki/Responsive_Web_Design" class='spip_out' rel='external'>responsive</a> by default, and load <a href="http://romy.tetue.net/837" class='spip_out' rel='external'>conditional selectors</a> for greater CSS flexibility.</p>
<h3 class="spip">New features</h3>
<p>SQLite support has been greatly improved, and this, because of its simplicity of installation, is now the default database format (if supported by the server) when a new site is installed.<span class="spip_note_ref"> [<a href='#nb8' class='spip_note' rel='footnote' title='Support for PostGreSQL, however, should be considered experimental and (...)' id='nh8'>8</a>]</span></p> <p>The management of editorial objects has been made generic. Therefore authors, documents, keywords, forums, versioning, and logos can be used on any object (all SPIP objects and also any editorial object added by a plugin following the new declaration API).<br class='autobr' />
The status, date of publication, language and translation is also generalised and can be used on any object by simple declaration.<br class='autobr' />
When the signalling of concurrent editing is enabled, any editable object is now included in the signalling.</p> <p>The identity of the site is complemented by a site slogan, something between the title and the description. It is displayed with the tag <strong><code class='spip_code' dir='ltr'>#SLOGAN_SITE_SPIP</code></strong>.</p> <p>The safety screen is included as standard.</p> <p>The level of tracking recorded in log files can be managed. By default, the logs are much less verbose in production and only report anomalies or important information. The log level can be adjusted for debug or development.</p> <p>The occasional cron job which was file-based has been deleted in favour of a queue of pending tasks (which also manages periodic tasks). This job queue makes it possible to program asynchronous actions<span class="spip_note_ref"> [<a href='#nb9' class='spip_note' rel='footnote' title='for example, to send an email “when it becomes possible,” allowing the user (...)' id='nh9'>9</a>]</span> and offers an easy to use API for plugin developers.</p> <p>The Ajax in templates (<code class='spip_code' dir='ltr'>{ajax}</code> on <code class='spip_code' dir='ltr'>INCLURE</code>) supports <a href="http://www.w3.org/WAI/intro/aria.php" class='spip_out' rel='external'>ARIA attributes</a>, improving its accessibility. In addition, the browsing history is also handled automatically through the API “History” of HTML5<span class="spip_note_ref"> [<a href='#nb10' class='spip_note' rel='footnote' title='in all modern browsers, except Internet Explorer, which does not yet (...)' id='nh10'>10</a>]</span>. The browser URL is updated automatically on ajax links allowing for problem-free backtracking.</p> <p><a href="http://www.spip.net/en_article3512.html" class='spip_in'>Models</a> used in text now automatically receive the environment of the template which display them.</p> <p>The forms of the private area use HTML5 features, for example the <code class='spip_code' dir='ltr'>required</code> and <code class='spip_code' dir='ltr'>placeholder</code> attributes.</p> <p>The characters <code class='spip_code' dir='ltr'># [] () {} <></code> can now be escaped in templates by using a slash: <strong><code class='spip_code' dir='ltr'>\</code></strong>. This makes it possible, for example, to write conditions on a check-box in a much more elegant way, without the square brackets of the <i>name</i> attribute interfering with those of the SPIP tag:</p>
<div class="coloration_code"><div class="spip_spip2 cadre spip_cadre"><div class="spip2"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #D05000;">[</span><span style="color: #D05000;">(</span><span style="color: #D05000;">#ENV</span><span style="color: #74B900;">{param}</span><span style="color: #FF851D;">|yes</span><span style="color: #D05000;">)</span> </div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> <label for='kindness'>With kindness?</label></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> <input type='checkbox' name='what_with<span style=""><span style="color:#FF2100; font-weight:bold;">\</span>[</span><span style=""><span style="color:#FF2100; font-weight:bold;">\</span>]</span>' id='kindness' checked='checked' value='kindness' /> </div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #D05000;">]</span> </div></li>
</ol></div></div></div><h3 class="spip">Shortcuts</h3>
<p>There is now a shortcut for abbreviations: <code class='spip_code' dir='ltr'>[NHS|National Health Service]</code> (or <code class='spip_code' dir='ltr'>[SNCF|Société Nationale des Chemins de fer Français{fr}]</code> to indicate a different language from the main text) generates an <strong><code class='spip_code' dir='ltr'>abbr</code></strong> tag<span class="spip_note_ref"> [<a href='#nb11' class='spip_note' rel='footnote' title='The tag is no longer used in HTML5.' id='nh11'>11</a>]</span>.</p> <p>Document models accept width or height arguments to limit their size: <strong><code class='spip_code' dir='ltr'><docxx|largeur=150></code></strong>.</p> <p>Double-entry tables (whether horizontally or vertically) are now handled correctly.</p> <p>It is no longer necessary to use the shortcut "<code class='spip_code' dir='ltr'> _ </code>" to produce a simple carriage return or line break. A carriage return in the text does the job. To maintain the previous behaviour, this feature can be disabled by placing <code class='spip_code' dir='ltr'>define ('_AUTOBR', '')</code> in <code class='spip_code' dir='ltr'>mes_options.php</code>.</p>
<h3 class="spip">Loops</h3>
<p>SPIP's system of loops has been generalised so that it applies no longer directly to a SQL table but to an iterator. An SQL iterator maintains the traditional operation of loops on SQL tables, but it is now possible to iterate over any given set of data: <a href="http://www.spip.net/fr_article5444.html" class='spip_in' hreflang='fr'>Les itérateurs de SPIP</a></p> <p>A first example of an application for this: the loop <strong><code class='spip_code' dir='ltr'>DATA</code></strong> extends the operation of loops to structured information in tabular form. It becomes possible to loop over a CSV file, or on a remote url that returns JSON information ... :</p>
<ul class="spip"><li> <a href="http://www.spip.net/fr_article5443.html" class='spip_in' hreflang='fr'>Exemples de <code class='spip_code' dir='ltr'>BOUCLE(DATA)</code> </a></li><li> <a href="http://zzz.rezo.net/La-boucle-iCalendar.html" class='spip_url spip_out auto' rel='nofollow external'>http://zzz.rezo.net/La-boucle-iCalendar.html</a></li><li> <a href="http://zzz.rezo.net/Exemples-de-boucles-YQL.html" class='spip_url spip_out auto' rel='nofollow external'>http://zzz.rezo.net/Exemples-de-boucles-YQL.html</a></li></ul>
<p>To ensure the easy migration of templates containing <code class='spip_code' dir='ltr'>POUR</code> and <code class='spip_code' dir='ltr'>CONDITION</code> loops, these loops are also supported as special cases of the <code class='spip_code' dir='ltr'>DATA</code> loop, with the previous syntax.</p>
<h3 class="spip">Criteria</h3>
<p><strong><code class='spip_code' dir='ltr'>{si ...}</code></strong>: lets you place a condition on the execution of a loop which depends on the context of the template rather than on values in the database.</p> <p><strong><code class='spip_code' dir='ltr'>{tri ...}</code></strong>: used with the <code class='spip_code' dir='ltr'>#TRI</code> tag <a href="http://www.spip.net/fr_article5429.html" class='spip_in' hreflang='fr'>for easy sorting</a>.</p> <p><strong><code class='spip_code' dir='ltr'>{feuille}</code></strong>: makes it possible to select sections without children (those at the bottom of the hierarchy).</p> <p><strong><code class='spip_code' dir='ltr'>{noeud}</code></strong>: makes it possible to select sections which have child sections.</p> <p><strong><code class='spip_code' dir='ltr'>{!racine}</code></strong>: excludes the first level sections (sectors).</p> <p><strong><code class='spip_code' dir='ltr'>{profondeur=3}</code></strong>: selects the only third-level sections (the root is level 0, sectors are level 1, then underneath, level 2 etc.).</p>
<h3 class="spip">Tags</h3>
<p>Models can have a cache if they contain the <strong><code class='spip_code' dir='ltr'>#CACHE</code></strong> tag, but by default they do not, as before.</p> <p>In the private area, templates are not cached either, unless <code class='spip_code' dir='ltr'>#CACHE</code> is present.</p> <p><strong><code class='spip_code' dir='ltr'>#LOGO_DOCUMENT</code></strong> may take arguments which determine the display mode of the logo:</p>
<ul class="spip"><li> <i>auto</i> (by default, corresponding to the mode of functioning in previous versions) automatically displays the thumbnail of the document if available, otherwise an overview, or else the icon for the document type.</li><li> <i>icone</i> indicates that the icon should be displayed.</li><li> <i>apercu</i> displays a preview image only, even if a thumbnail exists.</li><li> <i>vignette</i> displays the thumbnail of the document if it exists, otherwise nothing.</li></ul>
<p>The tag <strong><code class='spip_code' dir='ltr'>#SPIP_CRON</code></strong> is no longer used. If it is present in a template, it will be ignored.</p> <p><strong><code class='spip_code' dir='ltr'>#BOUTON_ACTION{label, url, class, confirm, title, callback}</code></strong> generates a mini HTML form with a button labelled “<i>label</i>” and clicking on it triggers a POST to “<i>url</i>”. It is better to use this button than a link when the “<i>url</i>” page will modify the database. If “<i>class</i>” contains the value “<i>ajax</i>”, the button will trigger a reload of the ajax block which contains it. “<i>confirm</i>” allows you to specify a message asking for user confirmation. “<i>title</i>” is the title attribute of the button, and “<i>callback</i>” the javascript function to call when the button is clicked.</p> <p><strong><code class='spip_code' dir='ltr'>#INFO_XXX{article, 13}</code></strong>: makes it possible to find the element <code class='spip_code' dir='ltr'>#XXX</code> without needing an <code class='spip_code' dir='ltr'>ARTICLES</code> loop. A similar code can be used for any loop and any tag of the loop: <code class='spip_code' dir='ltr'>#INFO_TITRE{article, 13}</code>,<code class='spip_code' dir='ltr'>#INFO_NOM{author, 2}</code>, ...</p> <p><strong><code class='spip_code' dir='ltr'>#CONFIG{name}</code></strong> displays the value of the configuration meta <i>name</i>. If the meta is an array, it is possible to directly access the values using the syntax <code class='spip_code' dir='ltr'>#CONFIG{name/subvalue}</code> which will return the <i>subvalue</i> of the meta <i>name</i>. To access the meta for a specific table of a plugin, use the syntax <code class='spip_code' dir='ltr'>#CONFIG{/metamyplugin/name}</code>: by starting with a <code class='spip_code' dir='ltr'>/</code>, we indicate that we want the meta name of the table spip_metamyplugin instead of using the spip_meta table of SPIP.<br class='autobr' />
In all cases, it is possible to specify a second argument to provide a default to be used if the meta does not exist: <code class='spip_code' dir='ltr'>#CONFIG{name, default_value}</code>.</p> <p>Like <code class='spip_code' dir='ltr'>#CONFIG{name/subvalue}</code>, the tags <strong><code class='spip_code' dir='ltr'>#ENV</code></strong>, <strong><code class='spip_code' dir='ltr'>#GET</code></strong> and <strong><code class='spip_code' dir='ltr'>#SESSION</code></strong> allow slashes to reach sub-array values, thus: <code class='spip_code' dir='ltr'>#ENV{name/subvalue}</code>, <code class='spip_code' dir='ltr'>#GET{table/key/subkey}</code>, <code class='spip_code' dir='ltr'>#SESSION{prefs/colour}</code>.</p> <p><strong><code class='spip_code' dir='ltr'>#PUBLISHED</code></strong>: tests the status (published or unpublished) of an object. Used in a loop, it implicitly deals with the current object. Otherwise it can be used with explicit arguments: <code class='spip_code' dir='ltr'>[(#PUBLISHED{article, 3}|oui) ... ]</code> on any other object.</p> <p><strong><code class='spip_code' dir='ltr'>#CLE</code></strong> and <strong><code class='spip_code' dir='ltr'>#VALEUR</code></strong> are the two tags that display the key and value in a <code class='spip_code' dir='ltr'>DATA</code> loop. <br class='autobr' />
<code class='spip_code' dir='ltr'>#VALEUR{x}</code> display the subvalue x if <code class='spip_code' dir='ltr'>#VALEUR</code> is an array (so, equivalent to <code class='spip_code' dir='ltr'>[(#VALEUR|table_valeur{x}) ]</code>). Several sub indexes can be stringed together, <code class='spip_code' dir='ltr'>#VALEUR{x/y/z}</code> in order to display a value in a sub-level of the array.</p> <p><strong><code class='spip_code' dir='ltr'>#PRODUIRE</code></strong> returns the name of a static file produced from a template. This is useful for a calculated stylesheet or a javascript file. The syntax is the same as for the <code class='spip_code' dir='ltr'>#INCLURE</code> tag: <code class='spip_code' dir='ltr'>#PRODUIRE{fond=mystyle.css, color=ffffff}</code> to use the template <code class='spip_code' dir='ltr'>mystyle.css.html</code></p> <p><strong><code class='spip_code' dir='ltr'>#LISTE{a,b,c}</code></strong> simply returns an array containing the values a, b and c. This is a simplified notation equivalent to <code class='spip_code' dir='ltr'>#ARRAY{0,a,1,b,2,c}</code>.</p> <p><strong><code class='spip_code' dir='ltr'>#TOTAL_UNIQUE</code></strong> returns the number of items displayed through the filter <code class='spip_code' dir='ltr'>|unique</code>. If <code class='spip_code' dir='ltr'>|unique{name}</code> is used, the same name must be referenced in the tag: <code class='spip_code' dir='ltr'>#TOTAL_UNIQUE{name}</code>.</p> <p><i>In the private area:</i></p> <p><strong><code class='spip_code' dir='ltr'>#AIDER{subtitle}</code></strong> will display a link to the section of SPIP's help under the heading <i>subtitle</i>.</p> <p><strong><code class='spip_code' dir='ltr'>#BOITE_OUVRIR</code></strong>, <strong><code class='spip_code' dir='ltr'>#BOITE_PIED</code></strong> and <strong><code class='spip_code' dir='ltr'>#BOITE_FERMER</code></strong> make the styled boxes of the editing area available for wider use:</p>
<ul class="spip"><li> <code class='spip_code' dir='ltr'>#BOITE_OUVRIR{title, class}</code> opens a box (<i>title</i> can be omitted). The styled classes are: <i>simple, info, notes, shortcuts</i> and <i>important</i>. </li><li> Any HTML after this tag is put in the box.</li><li> <code class='spip_code' dir='ltr'>#BOITE_PIED</code> to go to the bottom of the box when a footer is required.</li><li> <code class='spip_code' dir='ltr'>#BOITE_FERMER</code> closes the dialogue box.</li></ul>
<p>For many examples, see the page of the private area <i><code class='spip_code' dir='ltr'>ecrire/?exec=charte_boites</code></i> of the plugin <a href="http://plugins.spip.net/dev" class='spip_url spip_out' rel='external'>http://plugins.spip.net/dev</a></p> <p><strong><code class='spip_code' dir='ltr'>#FORMULAIRE_RECHERCHE_ECRIRE</code></strong> displays the search form of the private area. It can take two arguments. The first argument gives the URL to which it points, and the second, a class. In the presence of the javascript the form behaves as a link to the url passing the search parameter provided by the entered value. If the second argument is <i>ajax</i>, the form causes the reloading of the containing ajax block, in other words it acts as an Ajax link: <code class='spip_code' dir='ltr'>#FORMULAIRE_RECHERCHE_ECRIRE{#SELF, ajax}</code>.</p> <p><strong><code class='spip_code' dir='ltr'>#CHEMIN_IMAGE{article-24.png}</code></strong> returns the path to the icon <i>article-24.png</i> of the editing area theme currently in use by the logged-in user.</p>
<h3 class="spip">Filters</h3>
<p><strong><code class='spip_code' dir='ltr'>|lien_ou_expose</code></strong> can be used, for example, to build a menu with several links and marking the currently selected item with <code class='spip_code' dir='ltr'><strong></code> while maintaining a link <code class='spip_code' dir='ltr'><a></code> for other items. Example: <code class='spip_code' dir='ltr'>[(#URL_PAGE{mypage}|{lien_ou_expose{label, #ENV{page}|}=={mypage, class, title, rel})]</code>.</p> <p><strong><code class='spip_code' dir='ltr'>|singulier_ou_pluriel</code></strong> displays one string or another depending on the number to which it is applied: <code class='spip_code' dir='ltr'>[(#TOTAL_BOUCLE|singulier_ou_pluriel{1_article,nb_articles})]</code>. <i>1_article</i> and <i>nb_articles</i> are language strings that receive the number as an argument <code class='spip_code' dir='ltr'>@nb@</code>. If the number is zero, the filter is ignored.</p> <p><strong><code class='spip_code' dir='ltr'>|balise_img</code></strong> can quickly build an HTML <code class='spip_code' dir='ltr'><img></code> tag from a file name which includes the width and height for faster page rendering: <code class='spip_code' dir='ltr'>[(#CHEMIN{myimage.png}|balise_img{alt, class})]</code></p> <p><strong><code class='spip_code' dir='ltr'>|affdate_debut_fin</code></strong> displays an interval of time in a reader-friendly way, taking into account whether the start date and end date are or are not the same day, month or year, and displaying the time or not according to the second argument (<i>oui</i> or <i>non</i>. Example: <code class='spip_code' dir='ltr'>[(#DATE_DEBUT|date_debut_fin{#DATE_FIN, oui})]</code>.</p> <p><strong><code class='spip_code' dir='ltr'>|timestamp</code></strong> adds a timestamp in the form ?1234567890 to a filename, where the number represents the file date in seconds since 1 January 1970. This filter is useful, for example, when referencing a style sheet, in order to make sure that the browser will reload the file when it is changed:<br class='autobr' />
<code class='spip_code' dir='ltr'>[<link rel="stylesheet" href="(#CHEMIN{css/perso.css}|timestamp)" type="text/css" />]</code></p> <p><strong><code class='spip_code' dir='ltr'>|objet_icone</code></strong> returns the standard icon of a SPIP object. By default, the 24px version is returned, unless the size 16 or 32 is requested as an argument: <code class='spip_code' dir='ltr'>[(#OBJECT|objet_icone{16})]</code>.</p> <p><strong><code class='spip_code' dir='ltr'>|objet_info</code></strong> returns a property of a SPIP object as declared (or automatically supplied by SPIP) via the API <i>declarer_tables_objets_sql</i>.</p> <p><strong><code class='spip_code' dir='ltr'>|objet_afficher_nb</code></strong> displays the number of objects by taking into account the number to which the filter is applied and language strings declared for the object: <code class='spip_code' dir='ltr'>[(#TOTAL_BOUCLE|objet_afficher_nb{auteur})]</code>, for example, will display<i>1 author</i> or <i>23 authors</i>.</p> <p><strong><code class='spip_code' dir='ltr'>|wrap</code></strong> wraps an html tag around the text returned by the SPIP tag: <code class='spip_code' dir='ltr'>[(#TITLE|wrap{<h3>})]</code> will produce the same result as <code class='spip_code' dir='ltr'>[<h3>(#TITLE)</h3>]</code>.</p> <p><strong><code class='spip_code' dir='ltr'>|generer_info_entite</code></strong> displays a field of a SPIP object: <code class='spip_code' dir='ltr'>[(#ID_ARTICLE|generer_info_entite{article,titre})]</code> returns the title of the article <code class='spip_code' dir='ltr'>#ID_ARTICLE</code>. This is equivalent to <code class='spip_code' dir='ltr'>[(#INFO_TITRE{article,#ID_ARTICLE})]</code>.</p> <p><i>In the private area:</i></p> <p><strong><code class='spip_code' dir='ltr'>|icone_horizontale</code></strong> displays an icon of the private area in horizontal format. The syntax is: <code class='spip_code' dir='ltr'>[(#URL|{icone_horizontale{label,icon,function})]</code>. <i>icon</i> can be designated by an abbreviation (e.g.<i>article</i>) for a format of 24px, or else explicitly (<i>article-24.png</i>). The third argument, <i>function</i>, specifies the kind of action associated with the icon and can be one of the following: <i>add</i>, <i>del</i> <i>edit</i>, <i>new</i>, or else omitted. Example: <code class='spip_code' dir='ltr'>[(#URL_ECRIRE{auteur_edit,new=oui}|icone_horizontale{<:icone_creer_nouvel_auteur:>,auteur,new})]</code></p> <p><strong><code class='spip_code' dir='ltr'>|icone_verticale</code></strong> displays an icon of the private area in a vertical format. The syntax is the same as for <code class='spip_code' dir='ltr'>|icone_horizontale</code>.</p> <p><strong><code class='spip_code' dir='ltr'>|bouton_action_horizontal</code></strong> uses the same syntax as<code class='spip_code' dir='ltr'>|icone_horizontale</code> and displays a visually similar result. However the HTML markup will be of the same type as <code class='spip_code' dir='ltr'>#BOUTON_ACTION</code> to trigger a POST to the url and is therefore useful when the url makes a change to the database.</p> <p><strong><code class='spip_code' dir='ltr'>|sinon_interdire_acces</code></strong> placed anywhere in the page allows you to block access to it when the expression to which it applies is false. In this case an error page is displayed, unless a redirection URL is provided as an argument (you can then also provide an http redirect status as the second argument). It is generally used with an authorization check: <code class='spip_code' dir='ltr'>[(#AUTORISER{modifier,article,#ID_ARTICLE}|sinon_interdire_acces)]</code>.</p>
<h3 class="spip">JavaScript</h3>
<p><strong>SPIP 3</strong> uses the version 1.7.2 of jQuery and also includes jQuery UI (v. 1.8.20). It is possible to use a different version of jQuery in the public site simply by overloading <code class='spip_code' dir='ltr'>javascript /jquery.js</code> in the <code class='spip_code' dir='ltr'>squelettes/</code> directory without any risk of breaking the private area.</p> <p><strong>Ajax links:</strong> <br class='autobr' />
<code class='spip_code' dir='ltr'>.ajax</code> links no longer break the browsing history on browsers that support the <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html" class='spip_out' rel='external'>HTML5 History API</a> (Firefox, Safari, Chrome at the time of writing). That is to say that when you click on a link that reloads the SPIP ajax part of the page, the URL is updated in the browser and the visitor can click on the back button to return to the previous view.</p> <p>Special classes on ajax links:</p>
<ul class="spip"><li> <code class='spip_code' dir='ltr'>.nohistory</code> indicates that the link should not affect the browser history when clicked.</li><li> <code class='spip_code' dir='ltr'>.preload</code> tells SPIP that the content of the ajax link should be preloaded when the page loads. Thus a click on the link will produce immediate update.</li><li> <code class='spip_code' dir='ltr'>.nocache</code> tells SPIP that the contents loaded by the ajax link should not be cached. So several clicks on the same link will cause as many loads from the server (by default, only the first load is made for a given url and the content is then cached by the browser). </li></ul>
<p><strong>Reloading remote ajax blocks</strong><br class='autobr' />
An <code class='spip_code' dir='ltr'>.ajax</code> link, by default, reloads the block that contains it, but sometimes it is necessary to reload an ajax block elsewhere on the page.</p> <p>To achieve this, ajax blocks can be named when they are included: <br class='autobr' />
<code class='spip_code' dir='ltr'><INCLURE{fond=...,ajax=blockname} /></code>. The named block can then be reloaded by a call from <code class='spip_code' dir='ltr'>ajaxReload('blockname')</code>. A list of options can be passed as a second argument:</p>
<ul class="spip"><li> callback: callback function to be called after loading the ajax block.</li><li> args: list of arguments to be passed to the url when loading the block (makes it possible to change <code class='spip_code' dir='ltr'>#ENV</code> of an updated block).</li><li> history: whether or not the loading should affect the browsing history (default: false). Example:
<div class="coloration_code"><div class="spip_javascript cadre spip_cadre"><div class="javascript"><ol><li style="font-weight: normal; vertical-align:top;"><div style="">ajaxReload<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'blockname'</span><span style="color: #339933;">,</span> <span style="color: #009900;">{</span> </div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> callback<span style="color: #339933;">:</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">{</span><span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'done'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">}</span><span style="color: #339933;">,</span> </div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> args<span style="color: #339933;">:</span><span style="color: #009900;">{</span>id_article<span style="color: #339933;">:</span><span style="color: #CC0000;">3</span><span style="color: #009900;">}</span><span style="color: #339933;">,</span> </div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> history<span style="color: #339933;">:</span><span style="color: #003366; font-weight: bold;">false</span> </div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> <span style="color: #009900;">}</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></li>
</ol></div></div></div></li></ul>
<p><code class='spip_code' dir='ltr'>ajaxReload</code> can also be used on a jQuery selector in which case it will cause a reload of the smallest ajax block containing the target element. It then accepts only the one possible argument (the array of options): <code class='spip_code' dir='ltr'>$('#content').ajaxReload({args:{id_article:3}})</code></p> <p><strong>Javascript animations</strong> <br class='autobr' />
During interactions triggered by the user, it is possible to trigger several generic animations which are all applied to a <code class='spip_code' dir='ltr'>jQuery</code> selector:</p>
<ul class="spip"><li> <code class='spip_code' dir='ltr'>jQuery('#myid').animateLoading()</code> triggers the loading animation on <code class='spip_code' dir='ltr'>#myid</code> (automatically triggered by ajax reloading).</li><li> <code class='spip_code' dir='ltr'>jQuery('#myid').endLoading()</code> stops the loading animation on <code class='spip_code' dir='ltr'>#myid</code> (automatically triggered by ajax reloading).</li><li> <code class='spip_code' dir='ltr'>jQuery('#myid').animateAppend()</code> animates the block<code class='spip_code' dir='ltr'>#myid</code> to show it was just added by the interaction.</li><li> <code class='spip_code' dir='ltr'>jQuery('#myid').animateRemove()</code> animates the block<code class='spip_code' dir='ltr'>#myid</code> to show it was deleted by the interaction.</li></ul>
<p><strong>Utility functions:</strong> <br class='autobr' />
<code class='spip_code' dir='ltr'>parametre_url()</code> is used as a PHP version of the filter of the same name (<code class='spip_code' dir='ltr'>|parametre_url</code>) to add, delete, or retrieve parameters of a URL:</p>
<ul class="spip"><li> <code class='spip_code' dir='ltr'>parametre_url(url,arg,value)</code> adds <code class='spip_code' dir='ltr'>arg=value</code> to <code class='spip_code' dir='ltr'>url</code> and returns the modified URL.</li><li> <code class='spip_code' dir='ltr'>parametre_url(url,arg,'')</code> removes the value of <code class='spip_code' dir='ltr'>arg</code> from <code class='spip_code' dir='ltr'>url</code> and returns the modified URL.</li><li> <code class='spip_code' dir='ltr'>parametre_url(url,arg)</code> returns the value of <code class='spip_code' dir='ltr'>arg</code> in <code class='spip_code' dir='ltr'>url</code>.</li></ul>
<p><code class='spip_code' dir='ltr'>$('a').followLink()</code> follows a link by simulating a click on it (takes into account whether the link is an ajax link or not).</p> <p><strong>Popins in the private area:</strong> <br class='autobr' />
A link to a page in the private area with the class <code class='spip_code' dir='ltr'>.popin</code> opens a popin containing the centre of the target page (the <code class='spip_code' dir='ltr'>content/</code> block). The link retains its ability to be opened in new tab by a right click and in this case the full page is displayed.</p>
<h3 class="spip">API</h3>
<p><strong>SPIP 3</strong> brings several <strong>generic APIs</strong> to the management of editorial objects:</p>
<ul class="spip"><li> The API <a href="http://www.spip.net/fr_article5477.html" class='spip_in' hreflang='fr'><strong>editer_liens</strong></a> manages tables of links between any two objects.</li><li> The creation of new editorial objects is simplified by a <a href="http://www.spip.net/fr_article5525.html" class='spip_in' hreflang='fr'>declarative API</a>.</li><li> Management of the functions controlling the insertion, modification or publication of editorial objects: <a href="http://www.spip.net/fr_article5526.html" class='spip_in' hreflang='fr'>API <strong>editer_objet</strong></a>.</li><li> <strong><code class='spip_code' dir='ltr'>objet_test_si_publie($object, $id_object)</code></strong> tests if an object is published or not according to its status as declared (and according to a possible post-publication).</li><li> <strong><code class='spip_code' dir='ltr'>generer_url_ecrire_objet($object,$id_object,$args,$anchor)</code></strong> returns the url to the page of the object in the editing area. <code class='spip_code' dir='ltr'>$args</code> and <code class='spip_code' dir='ltr'>$anchor</code> are optional.</li><li> The pipeline <strong><code class='spip_code' dir='ltr'>optimiser_base_disparus</code></strong> is called when cleaning the database of objects which have been binned and the resulting dead links.</li></ul>
<p><strong>SPIP 3</strong> also has <a href="http://www.spip.net/fr_article5527.html" class='spip_in' hreflang='fr'><strong>management of a task queue</strong></a> which makes it possible to program tasks for future execution or simply set them as asynchronous (ASAP but without making the user wait).</p> <p>The implementation of plugin configuration is simplified by the automated support for forms: <strong><code class='spip_code' dir='ltr'>#FORMULAIRE_CONFIGURER_XXX</code></strong>, and by the functions <strong><code class='spip_code' dir='ltr'>lire_config</code></strong>, <strong><code class='spip_code' dir='ltr'>ecrire_config</code></strong> and <strong><code class='spip_code' dir='ltr'>effacer_config</code></strong> (see <a href="http://www.spip.net/fr_article5414.html" class='spip_in' hreflang='fr'>Configurer une fonctionnalité de votre site, ou un plugin</a>).</p> <p><a href="http://www.spip.net/en_article3980.html" class='spip_in' hreflang='en'>CVT forms</a> Make it easy to construct <a href="http://www.spip.net/fr_article5386.html" class='spip_in' hreflang='fr'>multi-page forms</a>, and also support <a href="http://www.spip.net/fr_article5428.html" class='spip_in' hreflang='fr'>automatic backup of text entry</a> upon simple declaration.<br class='autobr' />
The pipeline <strong><code class='spip_code' dir='ltr'>formulaire_fond</code></strong> provides a way to customize the background of forms (i.e. to edit the HTML of the form)<span class="spip_note_ref"> [<a href='#nb12' class='spip_note' rel='footnote' id='nh12'>12</a>]</span></p> <p><strong>In the SQL API:</strong></p>
<ul class="spip"><li> The <strong><code class='spip_code' dir='ltr'>sql_skip</code></strong> function is added: it allows you to skip a set number of results.</li><li> The values <code class='spip_code' dir='ltr'>null</code> in sql_updateq and sql_insertq are translated into <strong><code class='spip_code' dir='ltr'>NULL</code></strong> for SQL and are no longer treated as an empty string.</li><li> The functions <strong><code class='spip_code' dir='ltr'>sql_demarrer_transaction</code></strong> and <strong><code class='spip_code' dir='ltr'>sql_terminer_transaction</code></strong> as the names suggest, are used respectively to start or close an SQL transaction<span class="spip_note_ref"> [<a href='#nb13' class='spip_note' rel='footnote' title='Another function added, experimentally, is to bypass a problem of slowness (...)' id='nh13'>13</a>]</span>. </li></ul>
<p>A sandbox entry point, (<strong><code class='spip_code' dir='ltr'>public/sandbox.php</code></strong>) for template compilation, allows a plugin to manage the compilation of templates in a set of filters, to whitelist or blacklist functions, and to forbid PHP in templates.</p> <p><strong>Specialisation of criteria:</strong> <br class='autobr' />
It is possible to prefix the name of the criterion function with the server name and/or the name of the table. The search is carried out in this order:</p>
<ol class="spip"><li> <code class='spip_code' dir='ltr'>critere_serveur_TABLE_mycriterion_dist</code>, </li><li> <code class='spip_code' dir='ltr'>critere_serveur_TABLE_mycriterion</code>, </li><li> <code class='spip_code' dir='ltr'>critere_serveur_mycriterion_dist</code>, </li><li> <code class='spip_code' dir='ltr'>critere_serveur_mycriterion</code>, </li><li> <code class='spip_code' dir='ltr'>critere_TABLE_mycriterion_dist</code>, </li><li> <code class='spip_code' dir='ltr'>critere_TABLE_mycriterion</code>, </li><li> <code class='spip_code' dir='ltr'>critere_mycriterion_dist</code>, </li><li> <code class='spip_code' dir='ltr'>critere_mycriterion</code> </li></ol>
<p>In the file <code class='spip_code' dir='ltr'>options.php</code> of a plugin, or in the <code class='spip_code' dir='ltr'>mes_options.php</code> file, <strong><code class='spip_code' dir='ltr'>$GLOBALS['marqueur_skel'] .= ":prefix"</code></strong> can be used to differentiate the cache of compiled templates just as <code class='spip_code' dir='ltr'>$GLOBALS['marker'] .= ":prefix"</code> used to differentiate the cache of templates.</p></div>
		<hr />
		<div class='rss_notes'><div id='nb1'>
<p><span class="spip_note_ref">[<a href='#nh1' class='spip_note' title='Footnotes 1' rev='footnote'>1</a>] </span>Besides The Quill which was already integrated to SPIP 2, this movement includes Afficher Objets, Base CSS, multi-page CVT forms, Forum, Job queue, Mediabox, Media Library, TextWheel, Editable URLs, Comments, and others. Some of these have inspired the development of SPIP's core code, while others have been integrated after some alterations as new plugins.</p>
</div><div id='nb2'>
<p><span class="spip_note_ref">[<a href='#nh2' class='spip_note' title='Footnotes 2' rev='footnote'>2</a>] </span>This project has begun some time ago on SPIP-Zone, and those who have already used the plugins <i>Navigation du privé</i> or <i>Média Library</i> will recognise the changes.</p>
</div><div id='nb3'>
<p><span class="spip_note_ref">[<a href='#nh3' class='spip_note' title='Footnotes 3' rev='footnote'>3</a>] </span>For example, opening an article for editing becomes instantaneous thanks to Ajax pre-loading.</p>
</div><div id='nb4'>
<p><span class="spip_note_ref">[<a href='#nh4' class='spip_note' title='Footnotes 4' rev='footnote'>4</a>] </span><a href="http://core.spip.org/projects/spip/repository/revisions/17650" class='spip_url spip_out auto' rel='nofollow external'>http://core.spip.org/projects/spip/repository/revisions/17650</a></p>
</div><div id='nb5'>
<p><span class="spip_note_ref">[<a href='#nh5' class='spip_note' title='Footnotes 5' rev='footnote'>5</a>] </span>In SPIP 2.1 they were placed in the <code class='spip_code' dir='ltr'>extensions/</code> which now disappears.</p>
</div><div id='nb6'>
<p><span class="spip_note_ref">[<a href='#nh6' class='spip_note' title='Footnotes 6' rev='footnote'>6</a>] </span>This is an alternative, based on the library Colorbox, to plugins such as ThickBox, LightBox ...</p>
</div><div id='nb7'>
<p><span class="spip_note_ref">[<a href='#nh7' class='spip_note' title='Footnotes 7' rev='footnote'>7</a>] </span>Known in SPIP 2 under the name “Media Library”</p>
</div><div id='nb8'>
<p><span class="spip_note_ref">[<a href='#nh8' class='spip_note' title='Footnotes 8' rev='footnote'>8</a>] </span>Support for PostGreSQL, however, should be considered experimental and incomplete for production use.</p>
</div><div id='nb9'>
<p><span class="spip_note_ref">[<a href='#nh9' class='spip_note' title='Footnotes 9' rev='footnote'>9</a>] </span>for example, to send an email “when it becomes possible,” allowing the user to continue working without waiting for that email to actually be sent</p>
</div><div id='nb10'>
<p><span class="spip_note_ref">[<a href='#nh10' class='spip_note' title='Footnotes 10' rev='footnote'>10</a>] </span>in all modern browsers, except Internet Explorer, which does not yet support it</p>
</div><div id='nb11'>
<p><span class="spip_note_ref">[<a href='#nh11' class='spip_note' title='Footnotes 11' rev='footnote'>11</a>] </span>The tag <code class='spip_code' dir='ltr'><acronym></code> is no longer used in HTML5.</p>
</div><div id='nb12'>
<p><span class="spip_note_ref">[<a href='#nh12' class='spip_note' title='Footnotes 12' rev='footnote'>12</a>] </span><a href="http://core.spip.org/projects/spip/repository/revisions/18754" class='spip_url spip_out auto' rel='nofollow external'>http://core.spip.org/projects/spip/repository/revisions/18754</a></p>
</div><div id='nb13'>
<p><span class="spip_note_ref">[<a href='#nh13' class='spip_note' title='Footnotes 13' rev='footnote'>13</a>] </span>Another function added, experimentally, is <code class='spip_code' dir='ltr'>sql_preferer_transaction</code> to bypass a problem of slowness on multiple insertions on SQLite which are executed faster in transactional mode. This function returns<code class='spip_code' dir='ltr'>true</code> in SQLite only.</p>
</div></div>
		
		<img src="http://feeds.feedburner.com/~r/Spip/~4/Jnb0ouqE09k" height="1" width="1"/>]]></content:encoded>


		

	<feedburner:origLink>http://www.spip.net/en_article5533.html</feedburner:origLink></item>
<item xml:lang="fr">
		<title>SPIP 3.0</title>
		<link>http://feedproxy.google.com/~r/Spip/~3/SzNpIqXkcXg/fr_article5427.html</link>
		<guid isPermaLink="false">http://www.spip.net/fr_article5427.html</guid>
		<dc:date>2012-05-19T11:00:00Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>cerdic, tetue</dc:creator>


		<dc:subject>SPIP 3.0</dc:subject>

		<description>
&lt;p&gt;SPIP 3 : une nouvelle version marquée par la réécriture complète de l'espace privé en squelettes, une forte modularisation et une boucle DATA révolutionnaire.&lt;br class='autobr' /&gt;
SPIP 2.0 avait apporté les fonctionnalités permettant de l'utiliser comme un « framework » pour le développement d'applications Web, au-delà de sa vocation initiale de simple outil de publication.&lt;br class='autobr' /&gt;
SPIP 3 pousse la logique du « framework » jusqu'à se l'appliquer à lui-même : l'ensemble de l'espace privé de SPIP a été recodé en squelettes, sur la (...)&lt;/p&gt;


-
&lt;a href="http://www.spip.net/fr_rubrique155.html" rel="directory"&gt;Évolutions et mises à jour&lt;/a&gt;

/ 
&lt;a href="http://www.spip.net/@spip30" rel="tag"&gt;SPIP 3.0&lt;/a&gt;

		</description>


 <content:encoded><![CDATA[<img class='spip_logos' alt="" align="right" src="http://www.spip.net/local/cache-vignettes/L150xH95/arton5427-93cea.jpg" width='150' height='95' style='' />
		<div class='rss_chapo'><p><strong>SPIP 3</strong> : une nouvelle version marquée par la réécriture complète de l'espace privé en squelettes, une forte modularisation et une boucle DATA révolutionnaire.</p></div>
		<div class='rss_texte'><p><a href="http://www.spip.net/fr_article3784.html" class='spip_in' hreflang='fr'><span style='color: #273494;'>SPIP 2.0</span></a> avait apporté les fonctionnalités permettant de l'utiliser comme un « framework » pour le développement d'applications Web, au-delà de sa vocation initiale de simple outil de publication.</p> <p><strong>SPIP 3</strong> pousse la logique du « framework » jusqu'à se l'appliquer à lui-même : l'ensemble de l'espace privé de SPIP a été recodé en squelettes, sur la base des outils et fonctions proposés par le langage de squelettes de SPIP.</p> <p>Cette remise à plat de l'espace privé a été l'occasion de repenser le fonctionnement des objets éditoriaux et de normaliser leur usage pour le rendre le plus générique possible : la plupart des particularités historiques de chaque objet (et les exceptions de traitement associées dans le code de SPIP) ont été gommées pour être ramenées à une simple déclaration.</p> <p>La création de nouveaux objets éditoriaux et la personnalisation des objets existants deviennent ainsi beaucoup plus faciles et plus rapides.</p> <p><strong>SPIP 3</strong> achève également la découpe du logiciel en plugins comme SPIP 2 l'avait amorcé : l'ensemble des fonctionnalités proposées par SPIP 2 repose dorénavant sur un noyau <strong>SPIP 3</strong> accompagné de 23 plugins.</p> <p>La découpe complète du noyau a permis de compléter ses API et points d'entrée pour les développeurs de plugins.</p> <p><strong>SPIP 3</strong> se nourrit fortement des développements de la communauté SPIP-Zone, et marque une forte inversion : ce n'est plus le noyau qui tire les développements des plugins, mais les développements de plugins qui nourrissent l'avancée de SPIP par leurs expérimentations<span class="spip_note_ref"> [<a href='#nb1' class='spip_note' rel='footnote' title='Outre le Porte-plume déjà intégré dans SPIP 2 et qui initiait ce mouvement, on (...)' id='nh1'>1</a>]</span>.</p> <p>Parmi de nombreuses autres nouveautés fonctionnelles, <strong>SPIP 3</strong> introduit une nouvelle <a href="http://www.spip.net/fr_article5444.html" class='spip_in'>boucle DATA</a> qui permet enfin de boucler sur tout type de données et plus seulement sur les tables SQL. Il devient ainsi possible de parcourir soit une énumération, soit un <a href="http://www.spip.net/fr_article5443.html" class='spip_in'>fichier CSV, XML, YAML</a>... Plus fort encore, la boucle DATA permet directement de boucler sur une URL : il devient possible de parcourir directement une feuille de calcul Google Spreadsheet, un <a href="http://www.spip-contrib.net/Plugin-iCalendar" class='spip_out' hreflang='fr' rel='external'>calendrier en ligne</a>, une liste de <a href="http://zzz.rezo.net/Exemples-de-boucles-YQL.html" class='spip_out' hreflang='fr' rel='external'>vidéos sur Youtube</a>, des <a href="http://zzz.rezo.net/Exemples-de-boucles-YQL.html" class='spip_out' hreflang='fr' rel='external'>photos sur Flickr</a>… le Web devient votre base de données !</p> <p><strong>Prérequis</strong> :<br class='autobr' />
<strong><span style="color:#00CAD8">SPIP 3.0</span></strong> requiert désormais au minimum une version 5.1.0 de PHP pour pouvoir fonctionner correctement.</p>
<h3 class="spip">Un nouvel espace privé<span class="spip_note_ref"> [<a href='#nb2' class='spip_note' rel='footnote' title='Ce chantier avait été amorcé depuis quelque temps sur la Zone, et ceux qui (...)' id='nh2'>2</a>]</span></h3>
<p>Visuellement, l'espace privé demeure dans la continuité des versions précédentes, complétée de nouvelles icônes, avec :</p>
<ul class="spip"><li> pour les icônes principales de navigation, un <a href="http://sevcommunication.com/De-nouvelles-icones-pour-SPIP-3" class='spip_out' rel='external'>jeu spécifique réalisé pour SPIP par Sébastien Desbenoît</a>,</li><li> pour le reste de la page, l'adoption d'un jeu dérivé de FatCow.</li></ul>
<p>La refonte de l'interface est essentiellement technique, même si elle a également permis de résoudre un certain nombre de défauts ergonomiques historiques.</p> <p>La navigation principale est repensée et réorganisée. Le menu déroulant, désormais entièrement navigable au clavier, intègre aussi des temporisations pour faciliter son utilisation à la souris et être plus robuste aux mouvements mal contrôlés.</p> <p>L'ensemble de l'espace privé est donc réécrit sous forme de squelettes rangés dans le répertoire <strong><code class='spip_code' dir='ltr'>prive/squelettes</code></strong> organisés par sous-dossiers correspondants à un découpage de la page en blocs. Ce découpage est utilisé notamment pour le rafraîchissement des morceaux de page en Ajax, évitant le rechargement complet des pages et fluidifiant les interactions<span class="spip_note_ref"> [<a href='#nb3' class='spip_note' rel='footnote' title='Par exemple, le passage en édition sur un article devient instantané grâce au (...)' id='nh3'>3</a>]</span>.</p> <p>De nombreux points d'entrée (utilisés en premier lieu par les plugins du noyau) sont disponibles sous forme de pipeline pour permettre aux plugins d'étendre les fonctionnalités de l'espace privé.</p> <p>Les pages de l'espace privé sont réorganisées et renommées. En particulier toutes les pages d'objets éditoriaux utilisent un nommage cohérent fondé sur le nom de l'objet.</p> <p>La réécriture a également permis de remettre à niveau la structure complète du HTML et son accessibilité. Un référentiel a été mis en place pour que les développeurs de plugins puissent réutiliser les mêmes structures, et que les ajouts d'interface restent homogènes avec le noyau.</p> <p>Toutes les listes d'objet sont des squelettes qu'il devient facile de personnaliser. Elles bénéficient toutes du tri par colonne et de pagination ajax.</p> <p>Un système d'échafaudage des pages d'objet permet de construire automatiquement une interface minimale pour les nouveaux objets déclarés par les plugins. Chaque élément de cette interface par défaut peut ensuite être personnalisé en fonction des particularités de chaque objet :<span class="spip_note_ref"> [<a href='#nb4' class='spip_note' rel='footnote' id='nh4'>4</a>]</span>.</p> <p>Tous les formulaires interactifs sont écrits sous forme de formulaires CVT, ce qui permet d'assurer des interactions de qualité avec gestion systématique des messages d'erreur, vérification de saisie, ajax robuste à volonté, saisie multipage si nécessaire… Ils sont ainsi tous facilement extensibles par les plugins.</p> <p>Autre nouveauté, en mode édition, SPIP 3 prend en compte le retour à la ligne simple (il n'est désormais plus nécessaire d'utiliser « <code class='spip_code' dir='ltr'>_ </code> »).</p> <p>Enfin, l'espace privé intègre un mécanisme technique de thèmes qui permet de personnaliser les feuilles de style ou tout ou partie des icônes. Ce mécanisme pourra être utilisé par un plugin proposant des variantes activables par chaque utilisateur en fonction de ses préférences.</p>
<h3 class="spip">Modularisation en plugins</h3>
<p><strong>SPIP 3</strong> achève donc la découpe du logiciel en plugins. Son noyau conserve la gestion des articles, rubriques et auteurs ; le langage de squelettes et l'ossature de l'espace privé. Toutes les autres fonctionnalités sont externalisées dans des plugins, automatiquement installés dans la distribution par défaut de <strong>SPIP 3</strong>. Ces plugins fournis par défaut sont désormais placés dans un dossier <code class='spip_code' dir='ltr'>plugins-dist/</code><span class="spip_note_ref"> [<a href='#nb5' class='spip_note' rel='footnote' title='en SPIP 2.1 ils étaient placés dans le dossier désormais inutile.' id='nh5'>5</a>]</span></p> <p>Cette découpe du noyau a permis de compléter un certain nombre d'API implicites, maintenant à disposition des développeurs de plugins qui peuvent ainsi ajouter des fonctionnalités sans limite, en prenant modèle sur les plugins natifs de SPIP.</p> <p>Dans le domaine des plugins, <strong>SPIP 3</strong> amène également une refonte importante du formalisme de déclaration XML. Outre une lisibilité améliorée, cette évolution intègre la question des traductions de plugins, ainsi que les outils d'alimentation automatique d'un annuaire des plugins de SPIP et un outil de chargement.</p> <p>Par ailleurs, les plugins peuvent bénéficier des fonctions de mise à jour de base de données du core (avec reprise sur timeout) par simple déclaration de la procédure.</p> <p>Les plugins distribués par défaut avec SPIP sont :</p>
<ul class="spip"><li> <strong>Brèves</strong> s'occupe de l'objet éditorial Brèves.</li><li> <strong>Compagnon</strong> propose l'affichage de textes pédagogiques d'information et d'accompagnement lors des premiers accès à l'espace privé.</li><li> <strong>Compresseur</strong> déjà présent dans SPIP 2.1, prend en charge l'optimisation des performances du site en compressant et concaténant les feuilles de style CSS et les fichiers JavaScript embarqués dans la page. Cette version du plugin améliore des feuilles par média. Utilisation de @media pour concaténer tous les médias en un seul fichier sans en modifier l'ordre de chargement. Gestion des urls absolues sans protocole pour que les feuilles de style compressées fonctionnent sur http et https.</li><li> <strong>Dump</strong> assure la gestion des sauvegardes et restaurations. La fonctionnalité a été complètement ré-écrite pour assurer une sauvegarde complète et fiable. Le format de sauvegarde est maintenant SQLite et toutes les tables sont systématiquement conservées.</li><li> <strong>Forum</strong> gère l'objet éditorial <i>forum</i>, tant pour le site public que pour les interactions éditoriales dans l'espace privé. Outre une interface de modération repensée, les forums sont maintenant utilisables sur tous les objets éditoriaux de SPIP (natifs ou ajoutés par des plugins).</li><li> <strong>Images</strong>, déjà dans SPIP 2.1, prend en charge tous les filtres d'images et de couleurs dans les squelettes.</li><li> <strong>jQuery UI</strong> implémente dans SPIP la librairie complémentaire. jQuery UI facilite la création de composants graphiques dynamiques : onglets, drag & drop, barres de progression, widgets, effets…</li><li> <strong>Mediabox</strong> intègre dans SPIP par défaut une boîte <i>pop-in</i> pour visualiser les médias ou proposer des interactions<span class="spip_note_ref"> [<a href='#nb6' class='spip_note' rel='footnote' title='C'est une alternative aux plugin Thickbox, LightBox... qui repose sur la (...)' id='nh6'>6</a>]</span>.</li><li> <strong>Medias<span class="spip_note_ref"> [<a href='#nb7' class='spip_note' rel='footnote' title='Connu pour SPIP 2 sous le nom "Médiathèque"' id='nh7'>7</a>]</span></strong> prend en charge la gestion des documents et images. Il propose une refonte de l'interface et rend les documents utilisables sur n'importe quel objet éditorial.</li><li> <strong>Mots</strong> apporte la gestion des mots-clés et groupes de mots. Les mots-clés sont maintenant utilisables sur tous les objets éditoriaux.</li><li> <strong>Organiseur</strong> assure les fonctions de messagerie et calendrier interne de l'espace privé. L'interface est complètement refondue. La messagerie interne bénéficie de notification par email, et le calendrier repose sur la librairie FullCalendar qui permet une navigation fluide.</li><li> <strong>Pétitions</strong> gère les pétitions sur les articles et propose une interface de modération repensée.</li><li> <strong>Porte plume</strong>, déjà dans SPIP 2.1, assure l'aide à la saisie.</li><li> <strong>Révisions</strong> assure le versionage utilisable sur tous les objets éditoriaux de SPIP. L'interface de gestion des révisions est modernisée.</li><li> <strong>SafeHTML</strong>, déjà dans SPIP 2.1, prend en charge la sécurisation des contenus externes potentiellement dangereux.</li><li> <strong>Sites</strong> assure le fonctionnement de l'objet éditorial « Site syndiqué » ainsi que des articles syndiqués. Une interface de modération des articles syndiqués est proposée.</li><li> <strong>Squelettes par rubriques</strong> assure le fonctionnement des squelettes suffixés (article-2.html pour les articles de la rubrique 2 et de ses sous-rubriques).</li><li> <strong>Statistiques</strong> assure le calcul des statistiques du site et des articles, et propose un affichage complètement refondu.</li><li> <strong>Support vieux navigateur</strong>, déjà dans SPIP 2.1, propose des fonctions JavaScript activables pour permettre aux vieilles versions de navigateurs d'afficher correctement votre site.</li><li> <strong>Svp</strong> permet la gestion complète des plugins : installation, activation, mise à jour, recherche…</li><li> <strong>Textwheel</strong> est un moteur typographique qui supporte intégralement les raccourcis de SPIP, décrits désormais dans un fichier de règles au format YAML. Ce moteur permet une nette accélération du traitement des raccourcis (jusqu'à 2 fois plus rapide sur certains contenus), et facilite l'évolution et la personnalisation des raccourcis.</li><li> <strong>Urls Étendues</strong> supporte les URLs propres ou arborescentes, et propose une interface de configuration ainsi qu'une interface de gestion avancée optionnelle pour gérer finement les URLs de chaque page.</li><li> <strong>Vertèbres</strong>, déjà dans SPIP 2.1, permet au webmestre d'afficher le contenu d'une table SQL de SPIP au moyen d'un squelette généré automatiquement d'après la structure SQL de la table. Cet affichage se fait maintenant dans l'espace privé.</li></ul><h3 class="spip">Un nouveau jeu de squelettes par défaut</h3>
<p>Pour marquer le coup, les squelettes par défaut ont été révisés. Par la répartition en plusieurs feuilles de styles ré-utilisables indépendamment (<a href="http://romy.tetue.net/817" class='spip_out' rel='external'>méthode Daisy</a>, cf. <a href="http://spip-blog.net/703" class='spip_out' rel='external'>Un, deux, trois… feuilles CSS !</a>), ils constituent désormais un cadre de travail HTML/CSS modulaire, immédiatement utilisable pour démarrer un site. Ils proposent notamment un traitement typographique complet et harmonieux, inspiré du framework Blueprint. L'historique <code class='spip_code' dir='ltr'>spip_style.css</code> disparaît au profit de <strong><code class='spip_code' dir='ltr'>spip.css</code></strong>, qui peut être utilisée en complément de votre framework habituel.</p> <p>Les squelettes adoptent une nouvelle <a href="http://romy.tetue.net/826" class='spip_out' rel='external'>structure HTML de base</a> qui anticipe le HTML5, "responsive" par défaut, et embarque des <a href="http://romy.tetue.net/837" class='spip_out' rel='external'>sélecteurs conditionnels</a> pour plus de souplesse CSS.</p>
<h3 class="spip">De nouvelles fonctionnalités</h3>
<p>Le support de SQLite a été nettement amélioré, et c'est le format de base de données proposé par défaut lors d'une nouvelle installation (quand il est supporté par le serveur), compte tenu de sa simplicité de mise en œuvre<span class="spip_note_ref"> [<a href='#nb8' class='spip_note' rel='footnote' title='en revanche le support de PostGreSQL doit être considéré comme expérimental et (...)' id='nh8'>8</a>]</span>.</p> <p>La gestion des objets éditoriaux est généralisée. Par suite, les auteurs, documents, mots-clés, forums, révisions et logos sont utilisables sur n'importe quel objet (tous ceux de SPIP mais aussi tout objet éditorial ajouté par un plugin avec la nouvelle API de déclaration). <br class='autobr' />
La gestion du statut, de la date de publication, de la langue et de la traduction est également généralisée et utilisable sur tout objet par simple déclaration.<br class='autobr' />
Lorsque le signalement de l'édition concourante est activé, tout objet édité est désormais pris en compte dans le signalement.</p> <p>L'identité du site est complétée d'un slogan du site, entre titre et descriptif long, utilisable avec la balise <strong><code class='spip_code' dir='ltr'>#SLOGAN_SITE_SPIP</code></strong>.</p> <p>L'écran de sécurité est intégré en standard.</p> <p>Les logs (fichiers de trace) bénéficient d'une gestion par niveau d'importance. Par défaut, les logs sont beaucoup moins verbeux en production et ne signalent que les anomalies ou informations importantes. Le niveau de log peut être ajusté pour le debug ou le développement, permettant ainsi d'avoir toutes les informations nécessaires.</p> <p>Le cron périodique qui reposait sur des fichiers a été supprimé au profit d'une file de tâches en attente (qui gère aussi les tâches périodiques). Cette file de tâches permet de programmer des actions asynchrones<span class="spip_note_ref"> [<a href='#nb9' class='spip_note' rel='footnote' title='Par exemple, pour l'envoi d'un mail "dès que possible" qui permet de rendre la (...)' id='nh9'>9</a>]</span> et propose une API simple d'utilisation pour les développeurs de plugin.</p> <p>L'ajax des squelettes (<code class='spip_code' dir='ltr'>{ajax}</code> sur les <code class='spip_code' dir='ltr'>INCLURE</code>) bénéficie d'une prise en charge des attributs ARIA pour améliorer son accessibilité. De plus, l'historique de navigation est aussi automatiquement pris en charge grâce à l'API « History » de HTML5<span class="spip_note_ref"> [<a href='#nb10' class='spip_note' rel='footnote' title='dans tous les navigateurs modernes à l'exception de Internet Explorer qui ne (...)' id='nh10'>10</a>]</span>. L'URL du navigateur est donc mise à jour automatiquement sur les liens ajax, et permet les retours en arrière sans soucis.</p> <p>Les modèles utilisés dans du texte éditorial reçoivent automatiquement l'environnement du squelette dans lequel est affiché le texte<span class="spip_note_ref"> [<a href='#nb11' class='spip_note' rel='footnote' title='Voir Utiliser les modèles' id='nh11'>11</a>]</span>.</p> <p>Les formulaires des l'espace privé utilisent les possibilités de HTML5 avec par exemple les attributs <code class='spip_code' dir='ltr'>required</code> ou <code class='spip_code' dir='ltr'>placeholder</code>.</p> <p>Les squelettes peuvent maintenant échapper les caractères <code class='spip_code' dir='ltr'># [ ] ( ) { } < ></code> en utilisant une barre oblique <strong><code class='spip_code' dir='ltr'>\</code></strong>. Il devient possible d'écrire des conditions par exemple sur une case à cocher de formulaire de manière bien plus élégante, sans que les crochets de l'attribut <i>name</i> n'interfèrent avec les crochets de la balise englobante :</p>
<div class="coloration_code"><div class="spip_spip2 cadre spip_cadre"><div class="spip2"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #D05000;">[</span><span style="color: #D05000;">(</span><span style="color: #D05000;">#ENV</span><span style="color: #74B900;">{param}</span><span style="color: #FF851D;">|oui</span><span style="color: #D05000;">)</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> <label for='tendresse'>Avec tendresse ?</label></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> <input type='checkbox' name='avec_quoi<span style=""><span style="color:#FF2100; font-weight:bold;">\</span>[</span><span style=""><span style="color:#FF2100; font-weight:bold;">\</span>]</span>' id='tendresse' checked='checked' value='tendresse' /></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #D05000;">]</span></div></li>
</ol></div></div></div><h3 class="spip">Raccourcis</h3>
<p>Un raccourci pour les abréviations a été introduit nativement : <code class='spip_code' dir='ltr'>[SNCF|Société Nationale des Chemins de fer Français]</code> (ou <code class='spip_code' dir='ltr'>[CMS|Content Management System{en}]</code>) pour indiquer une langue différente du texte principal) génère une balise <strong><code class='spip_code' dir='ltr'>abbr</code></strong><span class="spip_note_ref"> [<a href='#nb12' class='spip_note' rel='footnote' title='La balise <acronym> n'est plus utilisée en HTML5.' id='nh12'>12</a>]</span>.</p> <p>Les modèles de document peuvent prendre en argument la largeur ou la hauteur pour réduire leur dimension : <strong><code class='spip_code' dir='ltr'><docxx|largeur=150></code></strong>.</p> <p>Les tableaux à 2 entrées (horizontale et verticale) sont désormais gérés correctement.</p> <p>Il n'est désormais plus nécessaire d'utiliser le raccourci « <code class='spip_code' dir='ltr'>_ </code> » pour produire un retour ligne simple.<br class='autobr' />
Pour retrouver le fonctionnement antérieur, ce nouveau comportement est débrayable en utilisant un <code class='spip_code' dir='ltr'>define('_AUTOBR', '');</code> dans son fichier <code class='spip_code' dir='ltr'>mes_options.php</code>.</p>
<h3 class="spip">Boucles</h3>
<p>Le système de boucles de SPIP a été généralisé pour s'appliquer non plus directement sur une table SQL mais sur un itérateur. Un itérateur SQL assure le fonctionnement historique des boucles sur les tables SQL, mais il devient possible de boucler sur toute donnée itérable : <a href="http://www.spip.net/fr_article5444.html" class='spip_in'>Les itérateurs de SPIP</a></p> <p>Premier exemple de nouvelle application : la boucle <strong><code class='spip_code' dir='ltr'>DATA</code></strong> étend le fonctionnement des boucles à toute information structurée sous forme de tableau. Il devient possible de boucler sur un fichier CSV, sur une url distante qui renvoie une information en JSON... :</p>
<ul class="spip"><li> <a href="http://www.spip.net/fr_article5443.html" class='spip_in'>Exemples de <code class='spip_code' dir='ltr'>BOUCLE(DATA)</code> </a></li><li> <a href="http://zzz.rezo.net/La-boucle-iCalendar.html" class='spip_url spip_out auto' rel='nofollow external'>http://zzz.rezo.net/La-boucle-iCalendar.html</a></li><li> <a href="http://zzz.rezo.net/Exemples-de-boucles-YQL.html" class='spip_url spip_out auto' rel='nofollow external'>http://zzz.rezo.net/Exemples-de-boucles-YQL.html</a></li></ul>
<p>Pour assurer la migration facile des squelettes qui utilisaient des boucles <code class='spip_code' dir='ltr'>POUR</code> et <code class='spip_code' dir='ltr'>CONDITION</code>, celles-ci sont également supportées comme cas particuliers de la boucle <code class='spip_code' dir='ltr'>DATA</code>, dans la même syntaxe que celle qui existait.</p>
<h3 class="spip">Critères</h3>
<p><strong><code class='spip_code' dir='ltr'>{si ...}</code></strong> : permet de conditionner l'exécution d'une boucle à la condition exprimée dans le critère, qui ne dépend pas des données en base mais du contexte du squelette.</p> <p><strong><code class='spip_code' dir='ltr'>{tri ...}</code></strong> : associé à la balise <code class='spip_code' dir='ltr'>#TRI</code> <a href="http://www.spip.net/fr_article5429.html" class='spip_in'>pour des tris faciles</a>.</p> <p><strong><code class='spip_code' dir='ltr'>{feuille}</code></strong> : permet de sélectionner les rubriques sans enfants (celles tout en bas de la hiérarchie).</p> <p><strong><code class='spip_code' dir='ltr'>{noeud}</code></strong> : permet de sélectionner les rubriques qui ont des enfants.</p> <p><strong><code class='spip_code' dir='ltr'>{!racine}</code></strong> : exclut les rubriques de la racine.</p> <p><strong><code class='spip_code' dir='ltr'>{profondeur=3}</code></strong> : permet de sélectionner les rubriques du 3e niveau (la racine est le niveau 0, les rubriques secteurs sont le niveau 1, puis les rubriques du dessous le niveau 2 etc ...).</p>
<h3 class="spip">Balises</h3>
<p>Les modèles peuvent avoir un cache s'ils contiennent une balise <strong><code class='spip_code' dir='ltr'>#CACHE</code></strong> (mais par défaut ils n'en ont pas, comme auparavant).</p> <p>Dans l'espace privé, les squelettes n'ont pas de cache non plus, sauf si une balise <code class='spip_code' dir='ltr'>#CACHE</code> est présente.</p> <p><strong><code class='spip_code' dir='ltr'>#LOGO_DOCUMENT</code></strong> peut prendre en argument le mode d'affichage du logo :</p>
<ul class="spip"><li> <i>auto</i> (par défaut, et c'est le fonctionnement historique) affiche automatiquement la vignette du document si existante, sinon un aperçu ; et sinon l'icône correspondant au type de document.</li><li> <i>icone</i> indique que c'est l'icône correspondant au type du fichier qui doit être affichée</li><li> <i>apercu</i> affiche un aperçu de l'image exclusivement, même si une vignette existe.</li><li> <i>vignette</i> affiche la vignette du document si elle existe, ou sinon rien.</li></ul>
<p>La balise <strong><code class='spip_code' dir='ltr'>#SPIP_CRON</code></strong> disparaît et n'a plus d'effet dans les squelettes où elle serait encore utilisée.</p> <p><strong><code class='spip_code' dir='ltr'>#BOUTON_ACTION{libellé, url, classe, confirm, title, callback}</code></strong> génère un mini formulaire HTML avec un seul bouton qui affiche « <i>libellé</i> » et déclenche au clic un POST vers « <i>url</i> ». Cette balise est à utiliser de préférence à un lien quand la page « <i>url</i> » modifie la base de données. Si la « <i>classe</i> » contient la valeur « <i>ajax</i> » le bouton déclenchera un rechargement du bloc ajax qui l'inclue. « <i>confirm</i> » permet d'indiquer un message pour faire confirmer l'action par l'utilisateur, « <i>title</i> » le contenu de l'attribut homonyme sur le bouton, et « <i>callback</i> » une fonction javascript à appeler lors du clic sur le bouton.</p> <p><strong><code class='spip_code' dir='ltr'>#INFO_XXX{article, 13}</code></strong> : permet de retrouver le <code class='spip_code' dir='ltr'>#XXX</code> sans faire une boucle <code class='spip_code' dir='ltr'>ARTICLES</code> sur l'article <code class='spip_code' dir='ltr'>13</code> (utilisable pour toute boucle et tout champ de la boucle : <code class='spip_code' dir='ltr'>#INFO_TITRE{article,13}</code>, <code class='spip_code' dir='ltr'>#INFO_NOM{auteur,2}</code>...)</p> <p><strong><code class='spip_code' dir='ltr'>#CONFIG{nom}</code></strong> permet d'afficher la valeur de la meta de configuration <i>nom</i>.<br class='autobr' />
Si la meta est un tableau, il est possible d'accéder directement à des sous valeurs avec la syntaxe <code class='spip_code' dir='ltr'>#CONFIG{nom/sousvaleur}</code> qui renverra la <i>sousvaleur</i> de la meta <i>nom</i>.<br class='autobr' />
Pour accéder à la meta d'une table spécifique à un plugin, il faut utiliser la syntaxe <code class='spip_code' dir='ltr'>#CONFIG{/metamonplugin/nom}</code> : en commençant par un <tt>/</tt>, on indique que l'on veut la meta nom de la table spip_metamonplugin au lieu de la table spip_meta de SPIP.<br class='autobr' />
Dans tous les cas, il est possible d'indiquer en second argument la valeur par défaut qui doit être utilisée si la meta n'existe pas encore : <code class='spip_code' dir='ltr'>#CONFIG{nom,valeurpardefaut}</code></p> <p>À l'instar de <code class='spip_code' dir='ltr'>#CONFIG{nom/sousvaleur}</code> les balises <strong><code class='spip_code' dir='ltr'>#ENV</code></strong>, <strong><code class='spip_code' dir='ltr'>#GET</code></strong>, <strong><code class='spip_code' dir='ltr'>#SESSION</code></strong> permettent d'utiliser des barres obliques pour obtenir des sous valeurs de tableau tel que :<code class='spip_code' dir='ltr'>#ENV{nom/sousvaleur}</code>, <code class='spip_code' dir='ltr'>#GET{tableau/cle/souscle}</code>, <code class='spip_code' dir='ltr'>#SESSION{prefs/couleur}</code>.</p> <p><strong><code class='spip_code' dir='ltr'>#PUBLIE</code></strong> : pour tester l'état (publié ou non) d'un objet. S'utilise dans une boucle, porte implicitement sur l'objet en cours ou avec des arguments explicites : <code class='spip_code' dir='ltr'>[(#PUBLIE{article, 3}|oui) ... ]</code>, sur tout autre objet.</p> <p><strong><code class='spip_code' dir='ltr'>#CLE</code></strong> et <strong><code class='spip_code' dir='ltr'>#VALEUR</code></strong> sont les deux balises qui permettent d'afficher la clé et la valeur dans une boucle <code class='spip_code' dir='ltr'>DATA</code><br class='autobr' />
<code class='spip_code' dir='ltr'>#VALEUR{x}</code> permet d'afficher la sous valeur de x si <code class='spip_code' dir='ltr'>#VALEUR</code> est un tableau (équivalent à <code class='spip_code' dir='ltr'>[(#VALEUR|table_valeur{x})]</code>). On peut enchaîner plusieurs sous index <code class='spip_code' dir='ltr'>#VALEUR{x/y/z}</code> pour afficher une valeur dans un sous-niveau du tableau.</p> <p><strong><code class='spip_code' dir='ltr'>#PRODUIRE</code></strong> : renvoie le nom d'un fichier statique produit à partir d'un squelette. Utile pour une feuille de style calculée ou un fichier javascript calculé. La syntaxe est la même que pour la balise <code class='spip_code' dir='ltr'>#INCLURE</code> : <code class='spip_code' dir='ltr'>#PRODUIRE{fond=mafeuille.css,couleur=ffffff}</code> pour utiliser le squelette <code class='spip_code' dir='ltr'>mafeuille.css.html</code></p> <p><strong><code class='spip_code' dir='ltr'>#LISTE{a,b,c}</code></strong> renvoie simplement un tableau contenant les valeurs a,b et c. C'est une écriture simplifiée de <code class='spip_code' dir='ltr'>#ARRAY{0,a,1,b,2,c}</code>.</p> <p><strong><code class='spip_code' dir='ltr'>#TOTAL_UNIQUE</code></strong> renvoie le nombre d'éléments affichés par l'intermédiaire du filtre <code class='spip_code' dir='ltr'>|unique</code>. Si on utilise <code class='spip_code' dir='ltr'>|unique{nom}</code>, il faut faire référence au même nom dans la balise : <code class='spip_code' dir='ltr'>#TOTAL_UNIQUE{nom}</code></p> <p><i>Dans l'espace privé :</i></p> <p><strong><code class='spip_code' dir='ltr'>#AIDER{surtitre}</code></strong> permet d'afficher un lien vers la section <i>surtitre</i> de l'aide de SPIP.</p> <p><strong><code class='spip_code' dir='ltr'>#BOITE_OUVRIR</code></strong>, <strong><code class='spip_code' dir='ltr'>#BOITE_PIED</code></strong> et <strong><code class='spip_code' dir='ltr'>#BOITE_FERMER</code></strong> permettent d'utiliser les boites stylées de l'espace privé :</p>
<ul class="spip"><li> <code class='spip_code' dir='ltr'>#BOITE_OUVRIR{titre,classe}</code> ouvre une boîte. le <i>titre</i> peut être omis. Les classes stylées dans l'espace privé sont : simple, info, note, raccourcis et important ;</li><li> le HTML qui suit est inclus dans la boîte ;</li><li> <code class='spip_code' dir='ltr'>#BOITE_PIED</code> permet de passer au pied de la boîte quand un pied est nécessaire.</li><li> <code class='spip_code' dir='ltr'>#BOITE_FERMER</code> ferme la boîte.</li></ul>
<p>Pour de nombreux exemples, voir la page de l'espace privé <i><code class='spip_code' dir='ltr'>ecrire/?exec=charte_boites</code></i> proposée par le plugin <a href="http://plugins.spip.net/dev" class='spip_url spip_out auto' rel='nofollow external'>http://plugins.spip.net/dev</a></p> <p><strong><code class='spip_code' dir='ltr'>#FORMULAIRE_RECHERCHE_ECRIRE</code></strong> affiche le formulaire de recherche de l'espace privé. On peut lui indiquer en premier argument l'url vers laquelle il doit pointer, et une classe en second argument. En présence de javascript le formulaire se comporte comme un lien vers url avec le paramètre recherche fourni par la saisie. Si on indique la classe ajax en second argument, le formulaire provoque le rechargement du bloc ajax incluant, comme un lien ajax donc : <code class='spip_code' dir='ltr'>#FORMULAIRE_RECHERCHE_ECRIRE{#SELF, ajax}</code></p> <p><strong><code class='spip_code' dir='ltr'>#CHEMIN_IMAGE{article-24.png}</code></strong> renvoie le chemin vers l'icône article-24.png du thème de l'espace privé en cours d'utilisation par l'auteur connecté.</p>
<h3 class="spip">Filtres</h3>
<p><strong><code class='spip_code' dir='ltr'>|lien_ou_expose</code></strong> permet de construire simplement un menu de plusieurs liens en exposant celui qui est sélectionné par un <code class='spip_code' dir='ltr'><strong></code> et en gardant un lien <code class='spip_code' dir='ltr'><a></code> sinon. Exemple : <code class='spip_code' dir='ltr'>[(#URL_PAGE{mapage}|lien_ou_expose{libelle, #ENV{page}|=={mapage}, classe, title, rel})]</code></p> <p><strong><code class='spip_code' dir='ltr'>|singulier_ou_pluriel</code></strong> affiche une chaîne ou une autre en fonction du nombre sur lequel il est appliqué : <code class='spip_code' dir='ltr'>[(#TOTAL_BOUCLE|singulier_ou_pluriel{1_article,nb_articles})]</code>. <i>1_article</i> et <i>nb_articles</i> sont des chaînes de langue qui reçoivent le nombre en argument <code class='spip_code' dir='ltr'>@nb@</code>. Si le nombre est zéro, le filtre n'affiche rien.</p> <p><strong><code class='spip_code' dir='ltr'>|balise_img</code></strong> permet de construire rapidement une balise HTML <code class='spip_code' dir='ltr'><img></code> à partir d'un nom de fichier en renseignant systématiquement le width et le height pour accélérer le rendu de la page : <code class='spip_code' dir='ltr'>[(#CHEMIN{monimage.png}|balise_img{alt,class})]</code></p> <p><strong><code class='spip_code' dir='ltr'>|affdate_debut_fin</code></strong> affiche sous forme sympathique un intervalle de temps entre une date de début et une date de fin, en prenant en compte le fait que la date de début et la date de fin sont ou non le même jour, le même mois, la même année, et en prenant en compte l'affichage de l'heure ou non (second argument, <i>oui</i> ou <i>non</i>. Exemple :<br class='autobr' />
<code class='spip_code' dir='ltr'>[(#DATE_DEBUT|affdate_debut_fin{#DATE_FIN,horaireouinon})]</code></p> <p><strong><code class='spip_code' dir='ltr'>|timestamp</code></strong> ajoute au nom d'un fichier un horodatage sous la forme ?1234567890 où le nombre représente la date du fichier compté en secondes depuis le 1er janvier 1970. Ce filtre est utile pour référencer par exemple des feuilles de styles en s'assurant que le navigateur les rechargera quand leur url change :<br class='autobr' />
<code class='spip_code' dir='ltr'>[<link rel="stylesheet" href="(#CHEMIN{css/perso.css}|timestamp)" type="text/css" />]</code></p> <p><strong><code class='spip_code' dir='ltr'>|objet_icone</code></strong> renvoie l'icône standard d'un objet de SPIP. Par défaut, la taille 24px est renvoyée sauf si la taille 16 ou 32 est demandée en argument : <code class='spip_code' dir='ltr'>[(#OBJET|objet_icone{16})]</code></p> <p><strong><code class='spip_code' dir='ltr'>|objet_info</code></strong> renvoie une propriété d'un objet de SPIP telle que déclarée (ou automatiquement renseignée par SPIP) via l'API <i>declarer_tables_objets_sql</i></p> <p><strong><code class='spip_code' dir='ltr'>|objet_afficher_nb</code></strong> affiche le nombre d'objets en prenant en compte le nombre auquel le filtre s'applique et les chaînes de langue déclarées pour l'objet : <code class='spip_code' dir='ltr'>[(#TOTAL_BOUCLE|objet_afficher_nb{auteur})]</code> affichera par exemple <i>1 auteur</i> ou <i>23 auteurs</i>.</p> <p><strong><code class='spip_code' dir='ltr'>|wrap</code></strong> encadre un texte d'une balise html : <code class='spip_code' dir='ltr'>[(#TITRE|wrap{<h3>})]</code> produit le même résultat que <code class='spip_code' dir='ltr'>[<h3>(#TITRE)</h3>]</code></p> <p><strong><code class='spip_code' dir='ltr'>|generer_info_entite</code></strong> affiche le champ d'un objet SPIP : <code class='spip_code' dir='ltr'>[(#ID_ARTICLE|generer_info_entite{article,titre})]</code> renvoie le titre mis en forme de l'article <code class='spip_code' dir='ltr'>#ID_ARTICLE</code>. C'est équivalent ici à <code class='spip_code' dir='ltr'>[(#INFO_TITRE{article,#ID_ARTICLE})]</code>.</p> <p><i>Dans l'espace privé :</i></p> <p><strong><code class='spip_code' dir='ltr'>|icone_horizontale</code></strong> affiche une icône de l'espace privé au format horizontal. La syntaxe est : <code class='spip_code' dir='ltr'>[(#URL|icone_horizontale{libelle,icone,fonction})]</code>. <i>icone</i> peut être désigné en abrégé (<i>article</i>) et sera alors au format 24px ou explicitement (<i>article-24.png</i>). Le 3ème argument <i>fonction</i> précise une famille d'action associée à l'icône et peut être au choix <i>add</i>, <i>del</i>, <i>edit</i>, <i>new</i>, ou omis. Exemple <code class='spip_code' dir='ltr'>[(#URL_ECRIRE{auteur_edit,new=oui}|icone_horizontale{<:icone_creer_nouvel_auteur:>,auteur,new})]</code></p> <p><strong><code class='spip_code' dir='ltr'>|icone_verticale</code></strong> affiche une icône de l'espace privé au format vertical. La syntaxe est la même que pour <code class='spip_code' dir='ltr'>|icone_horizontale</code></p> <p><strong><code class='spip_code' dir='ltr'>|bouton_action_horizontal</code></strong> utilise la même syntaxe que <code class='spip_code' dir='ltr'>|icone_horizontale</code> et affichera un résultat visuellement semblable. Cependant le markup HTML sera du même type que celui de <code class='spip_code' dir='ltr'>#BOUTON_ACTION</code> pour déclencher un POST vers l'url et est donc utile quand l'url modifie la base de données.</p> <p><strong><code class='spip_code' dir='ltr'>|sinon_interdire_acces</code></strong> placé à n'importe quel endroit de la page permet de bloquer l'accès à celle-ci quand l'expression à laquelle il s'applique est fausse. Dans ce cas une page d'erreur est affichée, sauf si une url de redirection est fournie en argument (on peut aussi alors fournir un status http de redirection en second argument). On l'utilise généralement sur une vérification d'autorisation <code class='spip_code' dir='ltr'>[(#AUTORISER{modifier,article,#ID_ARTICLE}|sinon_interdire_acces)]</code></p>
<h3 class="spip">JavaScript</h3>
<p><strong>SPIP 3</strong> utilise la version 1.7.2 de jQuery et intègre désormais jQuery UI en version 1.8.20. Il devient possible d'utiliser une version différente de jQuery dans le site public en surchargeant simplement <code class='spip_code' dir='ltr'>javascript/jquery.js</code> dans le dossier <code class='spip_code' dir='ltr'>squelettes/</code> sans risquer de casser l'espace privé.</p> <p><strong>Liens ajax :</strong><br class='autobr' />
Les liens <code class='spip_code' dir='ltr'>.ajax</code> ne cassent plus l'historique de navigation sur les navigateurs qui supportent <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html" class='spip_out' rel='external'>l'API HTML5 History</a> (Firefox, Safari, Chrome à la date de cet article). C'est-à-dire que lorsqu'on clique sur un lien ajax de SPIP qui recharge une partie de la page, l'URL est mise à jour dans le navigateur et le visiteur peut cliquer sur <i>Précédent</i> pour revenir en arrière.</p> <p>Classes spéciales sur les liens ajax :</p>
<ul class="spip"><li> <code class='spip_code' dir='ltr'>.nohistory</code> indique que le lien n'affecte pas l'historique de navigation lorsqu'il est cliqué ;</li><li> <code class='spip_code' dir='ltr'>.preload</code> indique à SPIP que le contenu du lien ajax doit être préchargé au moment où la page est chargée. Ainsi le clic sur le lien produira une mise à jour immédiate ;</li><li> <code class='spip_code' dir='ltr'>.nocache</code> indique à SPIP que le contenu du lien ajax ne doit pas être mis en cache. Ainsi plusieurs clics sur le même lien provoqueront autant de chargements depuis le serveur (par défaut, seul le premier chargement à lieu pour une url donnée et le contenu est ensuite mémorisé par le navigateur).</li></ul>
<p><strong>Rechargement télécommandé de blocs ajax :</strong><br class='autobr' />
Les liens <code class='spip_code' dir='ltr'>.ajax</code> permettent par défaut le rechargement du bloc ajax qui les contient, mais il est parfois nécessaire de provoquer le rechargement d'un autre bloc ajax de la page.</p> <p>Pour cela, il devient possible de nommer les blocs ajax au moment de leur inclusion :<br class='autobr' />
<code class='spip_code' dir='ltr'><INCLURE{fond=...,ajax=nomdubloc} /></code>. Le bloc ajax ainsi nommé peut ensuite être rechargé via l'appel de <code class='spip_code' dir='ltr'>ajaxReload('nomdubloc');</code>. Il est possible de passer en second argument une liste d'options contenant :</p>
<ul class="spip"><li> callback : fonction callback qui doit être appelée après le chargement ajax du bloc</li><li> args : liste d'argument qui seront passés à l'url lors du chargement du bloc (permet de modifier le <code class='spip_code' dir='ltr'>#ENV</code> du bloc mis à jour) ;</li><li> history : indique si le rechargement affecte ou non l'historique de navigation (faux par défaut).
Exemple : <div class="coloration_code"><div class="spip_javascript cadre spip_cadre"><div class="javascript"><ol><li style="font-weight: normal; vertical-align:top;"><div style="">ajaxReload<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'nomdubloc'</span><span style="color: #339933;">,</span> <span style="color: #009900;">{</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> callback<span style="color: #339933;">:</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">{</span><span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'fini'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">}</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> args<span style="color: #339933;">:</span><span style="color: #009900;">{</span>id_article<span style="color: #339933;">:</span><span style="color: #CC0000;">3</span><span style="color: #009900;">}</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> history<span style="color: #339933;">:</span><span style="color: #003366; font-weight: bold;">false</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> <span style="color: #009900;">}</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></li>
</ol></div></div></div></li></ul>
<p><code class='spip_code' dir='ltr'>ajaxReload</code> peut être utilisé également sur un sélecteur jQuery auquel cas il provoquera le rechargement du plus petit bloc ajax qui contient l'élément ciblé. Il ne prend alors qu'un argument possible (le tableau d'options) : <code class='spip_code' dir='ltr'>$('#contenu').ajaxReload({args:{id_article:3}})</code></p> <p><strong>Animations javascript :</strong><br class='autobr' />
Lors des interactions déclenchées par l'utilisateur, il est possible de déclencher plusieurs animations type qui s'appliquent toutes sur un sélecteur <code class='spip_code' dir='ltr'>jQuery</code> :</p>
<ul class="spip"><li> <code class='spip_code' dir='ltr'>jQuery('#monid').animateLoading()</code> déclenche l'animation de chargement sur <code class='spip_code' dir='ltr'>#monid</code> (automatiquement déclenchée lors des rechargements ajax)</li><li> <code class='spip_code' dir='ltr'>jQuery('#monid').endLoading()</code> arrête l'animation de chargement sur <code class='spip_code' dir='ltr'>#monid</code> (automatiquement déclenchée lors des rechargements ajax)</li><li> <code class='spip_code' dir='ltr'>jQuery('#monid').animateAppend()</code> anime le bloc <code class='spip_code' dir='ltr'>#monid</code> pour montrer qu'il vient d'être ajouté par l'interaction</li><li> <code class='spip_code' dir='ltr'>jQuery('#monid').animateRemove()</code> anime le bloc <code class='spip_code' dir='ltr'>#monid</code> pour montrer qu'il est supprimé par l'interaction</li></ul>
<p><strong>Fonctions utilitaires :</strong><br class='autobr' />
<code class='spip_code' dir='ltr'>parametre_url()</code> s'utilise comme sa version PHP de parametre_url pour ajouter, supprimer, récupérer des arguments d'une URL :</p>
<ul class="spip"><li> <code class='spip_code' dir='ltr'>parametre_url(url,arg,value)</code> ajoute <code class='spip_code' dir='ltr'>arg=value</code> à <code class='spip_code' dir='ltr'>url</code> et retourne l'url modifiée ;</li><li> <code class='spip_code' dir='ltr'>parametre_url(url,arg,'')</code> supprime la valeur de <code class='spip_code' dir='ltr'>arg</code> dans <code class='spip_code' dir='ltr'>url</code> et retourne l'url modifiée ;</li><li> <code class='spip_code' dir='ltr'>parametre_url(url,arg)</code> retourne la valeur de <code class='spip_code' dir='ltr'>arg</code> dans <code class='spip_code' dir='ltr'>url</code></li></ul>
<p><code class='spip_code' dir='ltr'>$('a').followLink()</code> suit le lien en simulant un clic dessus (prend en compte le fait que le lien est ou non un lien ajax).</p> <p><strong>Popin dans l'espace privé :</strong><br class='autobr' />
Un lien vers une page de l'espace privé avec une classe <code class='spip_code' dir='ltr'>.popin</code> provoque l'ouverture d'une popin qui contient le coeur de la page pointée (bloc <code class='spip_code' dir='ltr'>contenu/</code>). Le lien conserve sa capacité à être ouvert dans un autre onglet via clic droit et la page complète est affichée dans ce cas.</p>
<h3 class="spip">API</h3>
<p><strong>SPIP 3</strong> introduit plusieurs <strong>API génériques</strong> dans la gestion des objets éditoriaux :</p>
<ul class="spip"><li> une gestion générique des tables de liens d'un objet avec n'importe quel autre objet : c'est <a href="http://www.spip.net/fr_article5477.html" class='spip_in'>l'API <strong>editer_liens</strong></a></li><li> La création de nouveaux objets éditoriaux est simplifiée par <a href="http://www.spip.net/fr_article5525.html" class='spip_in'>une API déclarative</a></li><li> une gestion générique des fonctions d'insertion, modification ou publication des objets éditoriaux : <a href="http://www.spip.net/fr_article5526.html" class='spip_in'>l'API <strong>editer_objet</strong></a></li><li> <strong><code class='spip_code' dir='ltr'>objet_test_si_publie($objet, $id_objet)</code></strong> permet de tester facilement si un objet est publié ou non en fonction de son statut tel que déclaré (et en fonction d'une éventuelle post-publication)</li><li> <strong><code class='spip_code' dir='ltr'>generer_url_ecrire_objet($objet,$id_objet,$args, $ancre)</code></strong> renvoie l'url vers la page de l'objet dans l'espace privé. <code class='spip_code' dir='ltr'>$args</code> et <code class='spip_code' dir='ltr'>$ancre</code> sont optionnels.</li><li> le pipeline <strong><code class='spip_code' dir='ltr'>optimiser_base_disparus</code></strong> est appelé lors du nettoyage en base des objets à la poubelles et des liens morts qui en résultent</li></ul>
<p><strong>SPIP 3</strong> dispose également d'une <a href="http://www.spip.net/fr_article5527.html" class='spip_in'><strong>gestion de file de tâches</strong></a> qui permet de programmer l'exécution future ou simplement asynchone (ASAP mais sans faire attendre l'utilisateur) de fonctions.</p> <p>La mise en place de configuration des plugins est simplifiée par la prise en charge automatisée des formulaires <strong><code class='spip_code' dir='ltr'>#FORMULAIRE_CONFIGURER_XXX</code></strong> et par l'utilisation des fonctions <strong><code class='spip_code' dir='ltr'>lire_config</code></strong>, <strong><code class='spip_code' dir='ltr'>ecrire_config</code></strong>, <strong><code class='spip_code' dir='ltr'>effacer_config</code></strong> (voir <a href="http://www.spip.net/fr_article5414.html" class='spip_in' hreflang='fr'>Configurer une fonctionnalité de votre site, ou un plugin</a>).</p> <p>Les <a href="http://www.spip.net/fr_article3800.html" class='spip_in' hreflang='fr'>formulaires CVT</a> permettent facilement de faire <a href="http://www.spip.net/fr_article5386.html" class='spip_in'>des formulaires en plusieurs pages</a>, et supportent également <a href="http://www.spip.net/fr_article5428.html" class='spip_in'>la sauvegarde automatique de la saisie</a> par simple déclaration.<br class='autobr' />
Un pipeline <strong><code class='spip_code' dir='ltr'>formulaire_fond</code></strong> permet de personnaliser le fond des formulaires (pour modifier le HTML du formulaire)<span class="spip_note_ref"> [<a href='#nb13' class='spip_note' rel='footnote' id='nh13'>13</a>]</span></p> <p><strong>Dans l'API SQL :</strong></p>
<ul class="spip"><li> la fonction <strong><code class='spip_code' dir='ltr'>sql_skip</code></strong> est ajoutée et permet de sauter un certain nombre de résultats. </li><li> Les valeurs <code class='spip_code' dir='ltr'>null</code> dans sql_updateq et sql_insertq sont traduites en <strong><code class='spip_code' dir='ltr'>NULL</code></strong> SQL et ne sont plus assimilées à une chaîne vide.</li><li> les fonctions <strong><code class='spip_code' dir='ltr'>sql_demarrer_transaction</code></strong> et <strong><code class='spip_code' dir='ltr'>sql_terminer_transaction</code></strong> permettent respectivement comme leur nom le suggère de démarrer ou de clôturer une transaction SQL<span class="spip_note_ref"> [<a href='#nb14' class='spip_note' rel='footnote' title='Est ajouté de manière expérimentale également présent plutôt pour contourner un (...)' id='nh14'>14</a>]</span>.</li></ul>
<p>Introduction d'un point d'entrée bac-à-sable, (<strong><code class='spip_code' dir='ltr'>public/sandbox.php</code></strong>) pour la compilation des squelettes, permet à un plugin de gérer la compilation des squelettes dans un ensemble de filtres et fonctions en liste blanche ou liste noire, et d'interdire le PHP dans les squelettes.</p> <p><strong>Spécialisation des critères</strong> :<br class='autobr' />
Il est possible de préfixer par le nom du serveur et/ou le nom de la table le nom de la fonction critère. La recherche se fait dans l'ordre :</p>
<ol class="spip"><li> <code class='spip_code' dir='ltr'>critere_serveur_TABLE_moncritere_dist</code>,</li><li> <code class='spip_code' dir='ltr'>critere_serveur_TABLE_moncritere</code>,</li><li> <code class='spip_code' dir='ltr'>critere_serveur_moncritere_dist</code>,</li><li> <code class='spip_code' dir='ltr'>critere_serveur_moncritere</code>,</li><li> <code class='spip_code' dir='ltr'>critere_TABLE_moncritere_dist</code>,</li><li> <code class='spip_code' dir='ltr'>critere_TABLE_moncritere</code>,</li><li> <code class='spip_code' dir='ltr'>critere_moncritere_dist</code>,</li><li> <code class='spip_code' dir='ltr'>critere_moncritere</code></li></ol>
<p>Dans le fichier <code class='spip_code' dir='ltr'>options.php</code> d'un plugin ou dans le fichier <code class='spip_code' dir='ltr'>mes_options.php</code>, <strong><code class='spip_code' dir='ltr'>$GLOBALS['marqueur_skel'] .= ":prefixe"</code></strong> permet de différencier le cache des squelettes compilés comme <code class='spip_code' dir='ltr'>$GLOBALS['marqueur'] .= ":prefixe"</code> permettait déjà de différencier le cache des squelettes.</p></div>
		<hr />
		<div class='rss_notes'><div id='nb1'>
<p><span class="spip_note_ref">[<a href='#nh1' class='spip_note' title='Notes 1' rev='footnote'>1</a>] </span>Outre le Porte-plume déjà intégré dans SPIP 2 et qui initiait ce mouvement, on peut citer notamment les plugins Afficher_objets, Base CSS, Navigation du privé, CVT multi-étapes, Forum, Job-queue, Mediabox, Médiathèque, TextWheel, URLs éditables, Comments, qui ont, pour certains, inspiré fortement le développement de SPIP lui-même ; pour d'autres été intégrés, avec quelquefois certaines évolutions.</p>
</div><div id='nb2'>
<p><span class="spip_note_ref">[<a href='#nh2' class='spip_note' title='Notes 2' rev='footnote'>2</a>] </span>Ce chantier avait été amorcé depuis quelque temps sur la Zone, et ceux qui d'entre vous utilisaient déjà le plugin <i>Navigation du privé</i> ou la <i>médiathèque</i> retrouveront vite leurs marques.</p>
</div><div id='nb3'>
<p><span class="spip_note_ref">[<a href='#nh3' class='spip_note' title='Notes 3' rev='footnote'>3</a>] </span>Par exemple, le passage en édition sur un article devient instantané grâce au pré-chargement Ajax.</p>
</div><div id='nb4'>
<p><span class="spip_note_ref">[<a href='#nh4' class='spip_note' title='Notes 4' rev='footnote'>4</a>] </span><a href="http://core.spip.org/projects/spip/repository/revisions/17650" class='spip_url spip_out auto' rel='nofollow external'>http://core.spip.org/projects/spip/repository/revisions/17650</a></p>
</div><div id='nb5'>
<p><span class="spip_note_ref">[<a href='#nh5' class='spip_note' title='Notes 5' rev='footnote'>5</a>] </span>en SPIP 2.1 ils étaient placés dans le dossier <code class='spip_code' dir='ltr'>extensions/</code> désormais inutile.</p>
</div><div id='nb6'>
<p><span class="spip_note_ref">[<a href='#nh6' class='spip_note' title='Notes 6' rev='footnote'>6</a>] </span>C'est une alternative aux plugin Thickbox, LightBox... qui repose sur la librairie Colorbox</p>
</div><div id='nb7'>
<p><span class="spip_note_ref">[<a href='#nh7' class='spip_note' title='Notes 7' rev='footnote'>7</a>] </span>Connu pour SPIP 2 sous le nom "Médiathèque"</p>
</div><div id='nb8'>
<p><span class="spip_note_ref">[<a href='#nh8' class='spip_note' title='Notes 8' rev='footnote'>8</a>] </span>en revanche le support de PostGreSQL doit être considéré comme expérimental et incomplet pour un usage en production</p>
</div><div id='nb9'>
<p><span class="spip_note_ref">[<a href='#nh9' class='spip_note' title='Notes 9' rev='footnote'>9</a>] </span>Par exemple, pour l'envoi d'un mail "dès que possible" qui permet de rendre la main à l'utilisateur immédiatement sans devoir attendre que le mail soit effectivement envoyé</p>
</div><div id='nb10'>
<p><span class="spip_note_ref">[<a href='#nh10' class='spip_note' title='Notes 10' rev='footnote'>10</a>] </span>dans tous les navigateurs modernes à l'exception de Internet Explorer qui ne la supporte pas encore</p>
</div><div id='nb11'>
<p><span class="spip_note_ref">[<a href='#nh11' class='spip_note' title='Notes 11' rev='footnote'>11</a>] </span>Voir <a href="http://www.spip.net/fr_article3454.html" class='spip_in' hreflang='fr'>Utiliser les modèles</a></p>
</div><div id='nb12'>
<p><span class="spip_note_ref">[<a href='#nh12' class='spip_note' title='Notes 12' rev='footnote'>12</a>] </span>La balise <acronym> n'est plus utilisée en HTML5.</p>
</div><div id='nb13'>
<p><span class="spip_note_ref">[<a href='#nh13' class='spip_note' title='Notes 13' rev='footnote'>13</a>] </span><a href="http://core.spip.org/projects/spip/repository/revisions/18754" class='spip_url spip_out auto' rel='nofollow external'>http://core.spip.org/projects/spip/repository/revisions/18754</a></p>
</div><div id='nb14'>
<p><span class="spip_note_ref">[<a href='#nh14' class='spip_note' title='Notes 14' rev='footnote'>14</a>] </span>Est ajouté de manière expérimentale également <code class='spip_code' dir='ltr'>sql_preferer_transaction</code> présent plutôt pour contourner un problème de lenteur sur des insertions multiples avec SQLite, qui sont exécutées plus rapidement en mode transactionnel. Cette fonction renvoie <code class='spip_code' dir='ltr'>true</code> uniquement en SQLite</p>
</div></div>
		
		<img src="http://feeds.feedburner.com/~r/Spip/~4/SzNpIqXkcXg" height="1" width="1"/>]]></content:encoded>


		

	<feedburner:origLink>http://www.spip.net/fr_article5427.html</feedburner:origLink></item>
<item xml:lang="fr">
		<title>API de gestion de la file des travaux</title>
		<link>http://feedproxy.google.com/~r/Spip/~3/TkwSQv3_ikE/fr_article5527.html</link>
		<guid isPermaLink="false">http://www.spip.net/fr_article5527.html</guid>
		<dc:date>2012-05-19T09:50:41Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>cerdic</dc:creator>


		<dc:subject>SPIP 3.0</dc:subject>

		<description>
&lt;p&gt;SPIP 3.0 intègre nativement une interface de programmation (ou API) de gestion de file de travaux. Elle permet de programmer des tâches à exécuter dans le futur, ou simplement le plus tôt possible mais sans faire attendre l'utilisateur.&lt;br class='autobr' /&gt;
Les travaux programmés sont à tout moment visualisables dans l'espace d'administration via le menu Maintenance &gt; Liste des travaux. La page de suivi permet de forcer l'exécution immédiate d'une tâche, ou de supprimer certaines tâches.&lt;br class='autobr' /&gt;
Ajouter un travail dans la file (...)&lt;/p&gt;


-
&lt;a href="http://www.spip.net/fr_rubrique257.html" rel="directory"&gt;Guide des fonctions avancées&lt;/a&gt;

/ 
&lt;a href="http://www.spip.net/@spip30" rel="tag"&gt;SPIP 3.0&lt;/a&gt;

		</description>


 <content:encoded><![CDATA[<div class='rss_chapo'><p><a href="http://www.spip.net/fr_article5427.html" class='spip_in'><span style="color:#00CAD8">SPIP 3.0</span></a> intègre nativement une <a href="http://fr.wikipedia.org/wiki/Interface_de_programmation" class='spip_out' rel='external'>interface de programmation</a> (ou API) de gestion de file de travaux. Elle permet de programmer des tâches à exécuter dans le futur, ou simplement le plus tôt possible mais sans faire attendre l'utilisateur<span class="spip_note_ref"> [<a href='#nb1' class='spip_note' rel='footnote' title='Ces fonctionnalités étaient disponibles pour SPIP 2.1 dans le plugin (...)' id='nh1'>1</a>]</span>.</p></div>
		<div class='rss_texte'><p>Les travaux programmés sont à tout moment visualisables dans l'espace d'administration via le menu <i>Maintenance</i> > <i>Liste des travaux</i>. La page de suivi permet de forcer l'exécution immédiate d'une tâche, ou de supprimer certaines tâches.</p>
<h3 class="spip">Ajouter un travail dans la file</h3>
<textarea readonly='readonly' cols='40' rows='3' class='spip_cadre' dir='ltr'>$id_job = job_queue_add($function, $description, $arguments = array(), $file = '', $no_duplicate = FALSE, $time=0, $priority=0)</textarea>
<p>Avec les arguments :</p>
<ul class="spip"><li> <code class='spip_code' dir='ltr'>$function</code> : le nom de la fonction PHP qui doit être appelée</li><li> <code class='spip_code' dir='ltr'>$description</code> : une description humainement compréhensible de ce que fait la tache (essentiellement pour l'affichage dans la page de suivi de l'espace privé)</li><li> <code class='spip_code' dir='ltr'>$arguments</code> (facultatif, vide par défaut) : les arguments qui seront passés à la fonction, sous forme de tableau PHP </li><li> <code class='spip_code' dir='ltr'>$file</code> (facultatif, vide par défaut) : nom du fichier à inclure. Si le nom finit par un <code class='spip_code' dir='ltr'>/</code> alors on considère que c'est un répertoire et SPIP fera un <code class='spip_code' dir='ltr'>charger_fonction($function,$file)</code></li><li> <code class='spip_code' dir='ltr'>$no_duplicate</code> (facultatif, <code class='spip_code' dir='ltr'>false</code> par défaut) <ul class="spip"><li> si vaut <code class='spip_code' dir='ltr'>true</code> la tâche ne sera pas ajoutée si elle existe déjà en file d'attente avec la même fonction et les mêmes arguments.</li><li> si vaut <code class='spip_code' dir='ltr'>'function_only'</code> la tâche ne sera pas ajoutée si elle existe déjà en file d'attente avec la même fonction indépendamment de ses arguments</li></ul></li><li> <code class='spip_code' dir='ltr'>$time</code> (facultatif, <code class='spip_code' dir='ltr'>0</code> par défaut) indique la date sous forme de timestamp à laquelle la tâche doit être programmée. Si 0 ou une date passée, la tâche sera exécutée aussitôt que possible (en général en fin hit, en asynchrone).</li><li> <code class='spip_code' dir='ltr'>$priority</code> (facultatif, <code class='spip_code' dir='ltr'>0</code> par défaut) indique un niveau de priorité entre -10 et +10. Les tâches sont exécutées par ordre de priorité décroissante, une fois leur date d'exécution passée. La priorité est surtout utilisée quand une tâche cron indique qu'elle n'a pas fini et doit être relancée : dans ce cas SPIP réduit sa priorité pour être sûr que celle tâche ne monopolise pas la file d'attente.</li></ul>
<p>La fonction renvoie le numéro de travail ajouté ou 0 si aucun travail n'a été ajouté.</p>
<h3 class="spip">Supprimer un travail de la file</h3>
<textarea readonly='readonly' cols='40' rows='2' class='spip_cadre' dir='ltr'>job_queue_remove($id_job)</textarea>
<p><code class='spip_code' dir='ltr'>$id_job</code> est le numéro du travail en attente, tel que retourné par la fonction <code class='spip_code' dir='ltr'>job_queue_add</code></p> <p>La fonction retourne <code class='spip_code' dir='ltr'>true</code> si le travail a bien été trouvé et supprimé, <code class='spip_code' dir='ltr'>false</code> sinon.</p>
<h3 class="spip">Associer un travail à un objet éditorial</h3>
<textarea readonly='readonly' cols='40' rows='2' class='spip_cadre' dir='ltr'>job_queue_link($id_job,$objets)</textarea>
<p>Avec les arguments :</p>
<ul class="spip"><li> <code class='spip_code' dir='ltr'>$id_job</code> : le numéro de travail en attente, tel que retourné par la fonction <code class='spip_code' dir='ltr'>job_queue_add</code></li><li> <code class='spip_code' dir='ltr'>$objets</code> une liste d'objets sous la forme d'un tableau d'objets <code class='spip_code' dir='ltr'>array(array('objet'=>'article','id_objet'=>23),...)</code> </li></ul>
<p>Lorsque des travaux sont associés à un objet, ils apparaissent sur la page de l'espace privé de cet objet, et les auteurs qui ont le droit de modifier l'objet peuvent aussi supprimer le travail avant son exécution.</p></div>
		<hr />
		<div class='rss_notes'><div id='nb1'>
<p><span class="spip_note_ref">[<a href='#nh1' class='spip_note' title='Notes 1' rev='footnote'>1</a>] </span>Ces fonctionnalités étaient disponibles pour <a href="http://www.spip.net/fr_article4728.html" class='spip_in'><span style='color: #169249;'>SPIP 2.1</span></a> dans le plugin <a href="http://plugins.spip.net/queue.html" class='spip_out' rel='external'>job_queue</a></p>
</div></div>
		
		<img src="http://feeds.feedburner.com/~r/Spip/~4/TkwSQv3_ikE" height="1" width="1"/>]]></content:encoded>


		

	<feedburner:origLink>http://www.spip.net/fr_article5527.html</feedburner:origLink></item>
<item xml:lang="fr">
		<title>API « editer_objet »</title>
		<link>http://feedproxy.google.com/~r/Spip/~3/z5zvVsD12Kc/fr_article5526.html</link>
		<guid isPermaLink="false">http://www.spip.net/fr_article5526.html</guid>
		<dc:date>2012-05-19T09:49:54Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>cerdic</dc:creator>


		<dc:subject>SPIP 3.0</dc:subject>

		<description>
&lt;p&gt;L'ajout, la modification et la publication des instances d'objets éditoriaux sont simplifiés par une interface de programmation (ou API) constituée de 3 fonctions génériques qui peuvent servir pour manipuler tous les objets de SPIP.&lt;br class='autobr' /&gt;
Insérer&lt;br class='autobr' /&gt;
Une nouvelle instance d'un objet éditorial est créée en base par include_spip('action/editer_objet') ; $id_objet = objet_inserer($objet, $id_parent) ;&lt;br class='autobr' /&gt;
objet_inserer prend 2 arguments :&lt;br class='autobr' /&gt; $objet est le nom de l'objet inséré (article, breve,...)&lt;br class='autobr' /&gt; $id_parent (...)&lt;/p&gt;


-
&lt;a href="http://www.spip.net/fr_rubrique257.html" rel="directory"&gt;Guide des fonctions avancées&lt;/a&gt;

/ 
&lt;a href="http://www.spip.net/@spip30" rel="tag"&gt;SPIP 3.0&lt;/a&gt;

		</description>


 <content:encoded><![CDATA[<div class='rss_chapo'><p>L'ajout, la modification et la publication des instances d'objets éditoriaux sont simplifiés par une <a href="http://fr.wikipedia.org/wiki/Interface_de_programmation" class='spip_out' rel='external'>interface de programmation</a> (ou API) constituée de 3 fonctions génériques qui peuvent servir pour manipuler tous les objets de SPIP.</p></div>
		<div class='rss_texte'><h3 class="spip">Insérer</h3>
<p>Une nouvelle instance d'un objet éditorial est créée en base par</p>
<div class="coloration_code"><div class="spip_php cadre spip_cadre"><div class="php"><ol><li style="font-weight: normal; vertical-align:top;"><div style="">include_spip<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'action/editer_objet'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #000088;">$id_objet</span> <span style="color: #339933;">=</span> objet_inserer<span style="color: #009900;">&#40;</span><span style="color: #000088;">$objet</span><span style="color: #339933;">,</span> <span style="color: #000088;">$id_parent</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></li>
</ol></div></div><div class='cadre_download' style='text-align: right;'> <a href='http://www.spip.net/local/cache-code/fac8b6439ad1093a7e93087ce2cc9dbe.txt' style='font-family: verdana, arial, sans; font-weight: bold; font-style: normal;'>Télécharger</a></div></div>
<p><strong><code class='spip_code' dir='ltr'>objet_inserer</code> </strong> prend 2 arguments :</p>
<ul class="spip"><li> <code class='spip_code' dir='ltr'>$objet</code> est le nom de l'objet inséré (article, breve,...)</li><li> <code class='spip_code' dir='ltr'>$id_parent</code> (facultatif) est l'id du parent de l'objet (id_rubrique pour un article ou une breve, id_groupe pour un mot...)</li></ul>
<p>Les pipelines <i>pre_insertion</i> et <i>post_insertion</i> sont appelés automatiquement par la fonction.</p> <p>Si, pour l'objet demandé, une fonction spécifique <code class='spip_code' dir='ltr'>xxx_inserer</code> existe dans <code class='spip_code' dir='ltr'>action/editer_xxx</code>, elle sera automatiquement appelée par <code class='spip_code' dir='ltr'>objet_inserer</code> à la place du traitement générique.</p> <p>La fonction retourne l'id de l'enregistrement ajouté en base, ou 0 en cas d'échec.</p>
<h3 class="spip">Modifier</h3>
<p>Pour modifier une instance d'un objet en base, on utilise la fonction : <strong><code class='spip_code' dir='ltr'>objet_modifier</code></strong></p>
<div class="coloration_code"><div class="spip_php cadre spip_cadre"><div class="php"><ol><li style="font-weight: normal; vertical-align:top;"><div style="">include_spip<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'action/editer_objet'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="">objet_modifier<span style="color: #009900;">&#40;</span><span style="color: #000088;">$objet</span><span style="color: #339933;">,</span> <span style="color: #000088;">$id_objet</span><span style="color: #339933;">,</span> <span style="color: #000088;">$set</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></li>
</ol></div></div><div class='cadre_download' style='text-align: right;'> <a href='http://www.spip.net/local/cache-code/1248008d8c80c6af3753f657ba435929.txt' style='font-family: verdana, arial, sans; font-weight: bold; font-style: normal;'>Télécharger</a></div></div>
<p>Les 3 arguments :</p>
<ul class="spip"><li> <code class='spip_code' dir='ltr'>$objet</code> indique le nom de l'objet modifié</li><li> <code class='spip_code' dir='ltr'>$id_objet</code> donne l'id de l'objet modifié</li><li> <code class='spip_code' dir='ltr'>$set</code> est un tableau associatif champ=>valeur des champs modifiés</li></ul>
<p>La fonction appelle automatiquement les pipelines <i>pre_edition</i> et <i>post_edition</i>.</p> <p>Si pour l'objet demandé, une fonction spécifique <code class='spip_code' dir='ltr'>xxx_modifier</code> existe dans <code class='spip_code' dir='ltr'>action/editer_xxx</code>, elle sera automatiquement appelée par <code class='spip_code' dir='ltr'>objet_modifier</code> à la place du traitement générique.</p> <p>La fonction retourne une chaîne vide si tout s'est bien passé ou l'erreur en cas d'échec.</p> <p>La fonction <code class='spip_code' dir='ltr'>objet_modifier</code> vérifie les droits de l'auteur de la session en cours à faire l'action, via un appel à <code class='spip_code' dir='ltr'>autoriser('modifier', $objet, $id_objet)</code>. Si elle est appelée par une tâche anonyme, il sera nécessaire d'accorder une autorisation exceptionnelle comme indiquée dans <a href="http://www.spip.net/fr_article5528.html" class='spip_in'>API « autoriser »</a>.</p>
<h3 class="spip">Publier</h3>
<p>Pour la publication d'un objet (modification du statut ou de la date), il convient d'appeler la même fonction <code class='spip_code' dir='ltr'>objet_modifier</code> de la même façon que pour la modification.</p> <p>Cette fonction délègue à <strong><code class='spip_code' dir='ltr'>objet_instituer</code></strong> la mise à jour des champs qui concernent le statut de l'objet. Il est ainsi possible de modifier le contenu d'un objet et de le publier en un seul appel.</p> <p>Si une fonction <code class='spip_code' dir='ltr'>xxx_instituer</code> existe dans <code class='spip_code' dir='ltr'>action/editer_xxx</code> elle sera automatiquement appelée par <code class='spip_code' dir='ltr'>objet_instituer</code> à la place du traitement générique.</p> <p>La fonction <code class='spip_code' dir='ltr'>objet_instituer</code> vérifie les droits de l'auteur de la session en cours à faire l'action, via un appel à <code class='spip_code' dir='ltr'>autoriser('instituer', $objet, $id_objet)</code>. Si elle est appelée par une tâche anonyme, il sera nécessaire d'accorder une autorisation exceptionnelle comme indiquée dans <a href="http://www.spip.net/fr_article5528.html" class='spip_in'>API « autoriser »</a>.</p></div>
		
		<img src="http://feeds.feedburner.com/~r/Spip/~4/z5zvVsD12Kc" height="1" width="1"/>]]></content:encoded>


		

	<feedburner:origLink>http://www.spip.net/fr_article5526.html</feedburner:origLink></item>
<item xml:lang="fr">
		<title>API « autoriser »</title>
		<link>http://feedproxy.google.com/~r/Spip/~3/4W0dBBI4Efk/fr_article5528.html</link>
		<guid isPermaLink="false">http://www.spip.net/fr_article5528.html</guid>
		<dc:date>2012-05-19T09:49:00Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>cerdic</dc:creator>


		<dc:subject>SPIP 2.0</dc:subject>

		<description>
&lt;p&gt;L'interface de programmation (API) « autoriser » introduite dans SPIP 2.0 permet de gérer finement les autorisations données à un auteur d'effectuer une action sur un objet.&lt;br class='autobr' /&gt;
Vérifier une autorisation&lt;br class='autobr' /&gt;
La vérification d'une autorisation se fait par un appel de la forme :&lt;br class='autobr' /&gt; include_spip('inc/autoriser') ; if (autoriser('modifier', 'article', $id_article)) ...&lt;br class='autobr' /&gt;
La fonction autoriser($faire, $type, $id, $qui, $opt) accepte 5 arguments dont seul le premier est obligatoire :&lt;br class='autobr' /&gt; $faire est une chaîne qui désigne (...)&lt;/p&gt;


-
&lt;a href="http://www.spip.net/fr_rubrique257.html" rel="directory"&gt;Guide des fonctions avancées&lt;/a&gt;

/ 
&lt;a href="http://www.spip.net/@spip20" rel="tag"&gt;SPIP 2.0&lt;/a&gt;

		</description>


 <content:encoded><![CDATA[<div class='rss_chapo'><p>L'<a href="http://fr.wikipedia.org/wiki/Interface_de_programmation" class='spip_out' rel='external'>interface de programmation</a> (API) « autoriser » introduite dans <a href="http://www.spip.net/fr_article3784.html" class='spip_in'><span style='color: #273494;'>SPIP 2.0</span></a> permet de gérer finement les autorisations données à un auteur d'effectuer une action sur un objet.</p></div>
		<div class='rss_texte'><h3 class="spip">Vérifier une autorisation</h3>
<p>La vérification d'une autorisation se fait par un appel de la forme :</p>
<div class="coloration_code"><div class="spip_php cadre spip_cadre"><div class="php"><ol><li style="font-weight: normal; vertical-align:top;"><div style="">include_spip<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'inc/autoriser'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>autoriser<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'modifier'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'article'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$id_article</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">{</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #339933;">...</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #009900;">}</span></div></li>
</ol></div></div><div class='cadre_download' style='text-align: right;'> <a href='http://www.spip.net/local/cache-code/b2e4c855017ad3b87ef915ffc5425f8c.txt' style='font-family: verdana, arial, sans; font-weight: bold; font-style: normal;'>Télécharger</a></div></div>
<p>La fonction <code class='spip_code' dir='ltr'>autoriser($faire, $type, $id, $qui, $opt)</code> accepte 5 arguments dont seul le premier est obligatoire :</p>
<ul class="spip"><li> <strong><code class='spip_code' dir='ltr'>$faire</code></strong> est une chaîne qui désigne l'action soumise à autorisation. C'est en règle générale un verbe simple (<i>modifier</i>, <i>creer</i>, <i>supprimer</i>, <i>voir</i>, <i>configurer</i>...), parfois associé à un contexte (les mots sont alors collés : <i>changerlangue</i>, <i>publierdans</i>...). <br class='manualbr' />Il y a quelques exceptions où le <strong><code class='spip_code' dir='ltr'>$faire</code></strong> n'est pas un verbe et s'utilise sans aucun autre argument (<i><code class='spip_code' dir='ltr'>autoriser('webmestre')</code></i> par exemple, ou <i><code class='spip_code' dir='ltr'>autoriser('ecrire')</code></i> —qui désigne ici l'espace d'administration et non l'action—).</li><li> <strong><code class='spip_code' dir='ltr'>$type</code></strong> est une chaîne qui désigne sur quoi porte l'action. C'est en général le type d'un objet éditorial (article, rubrique, mot, groupe-mots, ...).</li><li> <strong><code class='spip_code' dir='ltr'>$id</code></strong> désigne l'id (la clé primaire) de l'objet sur lequel porte l'action. <strong><code class='spip_code' dir='ltr'>$id</code></strong> est en général un nombre entier, mais peut être une chaîne si cela correspond à la clé primaire de la table SQL concernée.</li><li> <strong><code class='spip_code' dir='ltr'>$qui</code></strong> désigne l'auteur (au sens SPIP) qui va faire l'action. Si il n'est pas fourni (ou <code class='spip_code' dir='ltr'>null</code> dans l'appel de la fonction autoriser, c'est implicitement l'auteur connecté qui est pris en compte. Sinon <strong><code class='spip_code' dir='ltr'>$qui</code></strong> peut être l'id_auteur d'un auteur dont on veut vérifier les droits, ou un tableau associatif qui décrit l'auteur (tableau qui contient alors les champs de la table spip_auteurs pour l'auteur concerné)</li><li> <strong><code class='spip_code' dir='ltr'>$opt</code></strong> est un tableau associatif de données supplémentaires contextuelles concernant l'action qui sont parfois utilisées par l'autorisation. Par exemple lorsqu'on veut modifier/publier un article, on appellera <code class='spip_code' dir='ltr'>autoriser('instituer', 'article', $id_article, null, array('statut' => 'publie'))</code></li></ul>
<p>La fonction <code class='spip_code' dir='ltr'>autoriser</code> retourne « <code class='spip_code' dir='ltr'>true</code> » ou « <code class='spip_code' dir='ltr'>false</code> » en fonction des droits de l'auteur à faire l'action demandée.</p> <p>Dans un squelette, la vérification d'une autorisation se fait par <a href="http://www.spip.net/fr_article3896.html" class='spip_in'>la balise <code class='spip_code' dir='ltr'>#AUTORISER</code></a>.</p>
<h3 class="spip">Donner une autorisation exceptionnelle</h3>
<p>Il arrive qu'on ait besoin de faire une action qui sera soumise à autorisation pour un auteur qui normalement n'en a pas le droit. Cela peut se produire, par exemple, dans le cas d'une <a href="http://www.spip.net/fr_article5527.html" class='spip_in'>action programmée</a> qui sera alors exécutée anonymement.</p> <p>Dans ce cas, il existe un mécanisme via la fonction <code class='spip_code' dir='ltr'>autoriser_exception</code> qui donne une autorisation exceptionnelle, le temps de réaliser l'action concernée.</p>
<div class="coloration_code"><div class="spip_php cadre spip_cadre"><div class="php"><ol><li style="font-weight: normal; vertical-align:top;"><div style="">include_spip<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'inc/autoriser'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #666666; font-style: italic;">// donner une autorisation exceptionnelle temporaire</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="">autoriser_exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'modifier'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'article'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$id_article</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #666666; font-style: italic;">// réaliser l'action désirée</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="">include_spip<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'action/editer_objet'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="">objet_modifier<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'article'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$id_article</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'titre'</span> <span style="color: #339933;">=></span> <span style="color: #0000ff;">'Nouveau titre'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #666666; font-style: italic;">// retirer l'autorisation exceptionnelle</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="">autoriser_exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'modifier'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'article'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$id_article</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></li>
</ol></div></div><div class='cadre_download' style='text-align: right;'> <a href='http://www.spip.net/local/cache-code/eff52ab9d71ec8072cd08ecd771795d7.txt' style='font-family: verdana, arial, sans; font-weight: bold; font-style: normal;'>Télécharger</a></div></div>
<p>La fonction <code class='spip_code' dir='ltr'>autoriser_exception($faire, $type, $id, $autoriser)</code> prend 4 arguments :</p>
<ul class="spip"><li> <strong><code class='spip_code' dir='ltr'>$faire</code></strong> avec la même signification que pour <code class='spip_code' dir='ltr'>autoriser()</code></li><li> <strong><code class='spip_code' dir='ltr'>$type</code></strong> avec la même signification que pour <code class='spip_code' dir='ltr'>autoriser()</code></li><li> <strong><code class='spip_code' dir='ltr'>$id</code></strong> avec la même signification que pour <code class='spip_code' dir='ltr'>autoriser()</code></li><li> <strong><code class='spip_code' dir='ltr'>$autoriser</code></strong> qui est un <i>booléen</i> et indique si l'autorisation exceptionnelle est accordée ou non :<ul class="spip"><li> Lorsque <code class='spip_code' dir='ltr'>$autoriser</code> vaut « <code class='spip_code' dir='ltr'>true</code> » ou n'est pas fourni, on accorde une autorisation exceptionnelle : tous les appels suivant à <code class='spip_code' dir='ltr'>autoriser()</code> avec les mêmes arguments <code class='spip_code' dir='ltr'>$faire, $type</code> et <code class='spip_code' dir='ltr'>$id</code> renverront <code class='spip_code' dir='ltr'>true</code></li><li> Lorsque <code class='spip_code' dir='ltr'>$autoriser</code> vaut « <code class='spip_code' dir='ltr'>false</code> » cela signifie que l'autorisation revient sous le régime normal et sera vérifiée selon la règle en vigueur (elle peut donc être encore autorisée ou effectivement interdite). Le <code class='spip_code' dir='ltr'>false</code> n'indique donc pas ici qu'on interdit l'action, mais simplement qu'il n'y a plus d'exception.</li></ul></li></ul><h3 class="spip">Déclarer une nouvelle autorisation</h3>
<p>Lorsque la fonction générique <code class='spip_code' dir='ltr'>autoriser()</code> est appelée, elle cherche une fonction nommée à laquelle déléguer la vérification.</p> <p>Si aucun <code class='spip_code' dir='ltr'>$type</code> n'est fourni dans l'appel à <code class='spip_code' dir='ltr'>autoriser()</code>, la recherche de la fonction se fait dans l'ordre suivant :</p>
<ul class="spip"><li> autoriser_<i>$faire</i></li><li> autoriser_<i>$faire</i>_dist</li><li> autoriser_defaut</li><li> autoriser_defaut_dist</li></ul>
<p>Si un <code class='spip_code' dir='ltr'>$type</code> est fourni dans l'appel à <code class='spip_code' dir='ltr'>autoriser()</code>, la recherche se fait dans l'ordre suivant :</p>
<ul class="spip"><li> autoriser_<i>$type</i>_<i>$faire</i></li><li> autoriser_<i>$type</i>_<i>$faire</i>_dist</li><li> autoriser_<i>$type</i></li><li> autoriser_<i>$type</i>_dist</li><li> autoriser_<i>$faire</i></li><li> autoriser_<i>$faire</i>_dist</li><li> autoriser_defaut</li><li> autoriser_defaut_dist</li></ul>
<p>Dans les deux cas, la recherche va du plus précis vers le plus général. Cela permet de définir des familles d'autorisation avec une règle générale (pour une action par exemple), que l'on précise ensuite pour certains objets qui suivent une règle différente.</p> <p>Pour définir une autorisation, il suffit donc de créer une fonction avec l'un des noms de la liste ci-dessus. La fonction recevra en arguments ceux envoyés à la fonction <code class='spip_code' dir='ltr'>autoriser()</code> et doit renvoyer « <code class='spip_code' dir='ltr'>true</code> » ou « <code class='spip_code' dir='ltr'>false</code> ».</p> <p>On peut définir une autorisation générique. Lorsque c'est une autorisation qui n'est pas encore définie, on la suffixe en général par un <i>_dist</i> qui permet toujours à un webmestre de la surcharger dans son fichier <code class='spip_code' dir='ltr'>mes_options.php</code> (en déclarant la fonction de même nom, mais sans son suffixe <i>_dist</i>).</p> <p><strong>Attention :</strong> on voit que dans le nom de la fonction, l'ordre de <code class='spip_code' dir='ltr'>$faire</code> et <code class='spip_code' dir='ltr'>$type</code> est inversé par rapport à celui de l'appel à <code class='spip_code' dir='ltr'>autoriser()</code>.</p> <p>À noter également qu'à partir de <a href="http://www.spip.net/fr_article5427.html" class='spip_in'><span style="color:#00CAD8">SPIP 3.0</span></a> le <code class='spip_code' dir='ltr'>$type</code> est présumé correspondre à un objet, et est normalisé lors de l'appel : vérification qu'il correspond bien à un type d'objet et sinon suppression du « s » final. Cela permet d'assurer qu'on appellera bien la bonne fonction d'autorisation même si on utilise un synonyme du <code class='spip_code' dir='ltr'>$type</code> (syndic au lieu de site par exemple, ou groupes_mot au lieu de groupe_mots qui est une exception de nommage).<br class='manualbr' />Il est cependant possible d'échapper à cette normalisation en préfixant le <code class='spip_code' dir='ltr'>$type</code> par un '_' (underscore) dans l'appel à <code class='spip_code' dir='ltr'>autoriser()</code>.</p> <p>Dans tous les cas, tous les autres caractères '_' sont retirés du <code class='spip_code' dir='ltr'>$type</code></p> <p>Ainsi un appel à <code class='spip_code' dir='ltr'>autoriser('modifier', 'groupes_mots', $id_groupe)</code> délèguera à la fonction <code class='spip_code' dir='ltr'>autoriser_groupemots_modifier()</code> (ou l'une des variantes selon la règle ci-dessus si cette fonction précise n'existe pas).<br class='autobr' />
Dans les versions antérieures à <a href="http://www.spip.net/fr_article5427.html" class='spip_in'><span style="color:#00CAD8">SPIP 3.0</span></a> il convient de toujours faire très attention à bien utiliser le nom de l'objet sans erreur, car sinon l'autorisation par défaut sera appelée ce qui peut conduire à une erreur d'autorisation plus ou moins grave selon le cas.</p> <p><strong>Exemple de fonction d'autorisation :</strong></p>
<div class="coloration_code"><div class="spip_php cadre spip_cadre"><div class="php"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #009933; font-style: italic;">/**</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #009933; font-style: italic;"> * Autoriser a creer un article :</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #009933; font-style: italic;"> * Il faut qu'une rubrique existe et qu'on ait le statut necessaire pour creer</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #009933; font-style: italic;"> * </span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #009933; font-style: italic;"> * @return bool</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #009933; font-style: italic;"> */</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #000000; font-weight: bold;">function</span> autoriser_article_creer_dist<span style="color: #009900;">&#40;</span><span style="color: #000088;">$faire</span><span style="color: #339933;">,</span> <span style="color: #000088;">$type</span><span style="color: #339933;">,</span> <span style="color: #000088;">$id</span><span style="color: #339933;">,</span> <span style="color: #000088;">$qui</span><span style="color: #339933;">,</span> <span style="color: #000088;">$opt</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">{</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>sql_countsel<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'spip_rubriques'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">></span><span style="color: #cc66cc;">0</span> AND <a href="http://www.php.net/in_array"><span style="color: #990000;">in_array</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$qui</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'statut'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'0minirezo'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'1comite'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #009900;">}</span></div></li>
</ol></div></div><div class='cadre_download' style='text-align: right;'> <a href='http://www.spip.net/local/cache-code/1ec48e63bfe96401f815fa46a35c873e.txt' style='font-family: verdana, arial, sans; font-weight: bold; font-style: normal;'>Télécharger</a></div></div><h3 class="spip">Aide au développement</h3>
<p>Lors du développement d'un plugin, il peut être utile de comprendre comment sont appelées les autorisations et dans quel ordre d'enchaînement.</p> <p>Pour cela il suffit d'ajouter la ligne suivante dans le fichier <a href="http://www.spip.net/fr_article4654.html" class='spip_in'><code class='spip_code' dir='ltr'>mes_options.php</code></a> :</p>
<div class="coloration_code"><div class="spip_php cadre spip_cadre"><div class="php"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><a href="http://www.php.net/define"><span style="color: #990000;">define</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'_DEBUG_AUTORISER'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></li>
</ol></div></div></div>
<p>Chaque appel à <code class='spip_code' dir='ltr'>autoriser()</code> sera alors tracé dans le fichier <i>spip.log</i> avec le nom de la fonction appelée et le résultat qu'elle a retourné.</p></div>
		
		<img src="http://feeds.feedburner.com/~r/Spip/~4/4W0dBBI4Efk" height="1" width="1"/>]]></content:encoded>


		

	<feedburner:origLink>http://www.spip.net/fr_article5528.html</feedburner:origLink></item>
<item xml:lang="fr">
		<title>#HTML5</title>
		<link>http://feedproxy.google.com/~r/Spip/~3/BXBeBDM-DnY/fr_article5057.html</link>
		<guid isPermaLink="false">http://www.spip.net/fr_article5057.html</guid>
		<dc:date>2012-05-19T09:31:16Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>davux</dc:creator>


		<dc:subject>SPIP 3.0</dc:subject>

		<description>
&lt;p&gt;Permet de tester si le site est en HTML5.&lt;br class='autobr' /&gt;
Il arrive souvent que SPIP, ainsi que les plugins, génèrent des bouts de code HTML sur le site public. Avec l'arrivée du HTML5, on a désormais la possibilité de produire du HTML plus sémantique, que ce soit par les nouvelles balises, les nouveaux éléments de formulaire, etc.&lt;br class='autobr' /&gt;
Cependant, sil l'on souhaite continuer à avoir un site valide au sens du W3C (organisme de standardisation du langage HTML entre autres), il est nécessaire que l'utilisation de code (...)&lt;/p&gt;


-
&lt;a href="http://www.spip.net/fr_rubrique543.html" rel="directory"&gt;Balises&lt;/a&gt;

/ 
&lt;a href="http://www.spip.net/@spip30" rel="tag"&gt;SPIP 3.0&lt;/a&gt;

		</description>


 <content:encoded><![CDATA[<div class='rss_chapo'><p>Permet de tester si le site est en HTML5.</p></div>
		<div class='rss_texte'><p>Il arrive souvent que SPIP, ainsi que les plugins, génèrent des bouts de code HTML sur le site public. Avec l'arrivée du HTML5, on a désormais la possibilité de produire du HTML plus sémantique, que ce soit par les nouvelles balises, les nouveaux éléments de formulaire, etc.</p> <p>Cependant, sil l'on souhaite continuer à avoir un site valide au sens du W3C (organisme de standardisation du langage HTML entre autres), il est nécessaire que l'utilisation de code HTML5 soit accompagnée de la déclaration du <i>doctype</i> suivant :</p>
<div class="coloration_code"><div class="spip_xml cadre spip_cadre"><div class="xml"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #00bbdd;"><!DOCTYPE html></span></div></li>
</ol></div></div></div>
<p>Cela signifie donc que SPIP et les plugins ne peuvent pas utiliser aveuglément des éléments de HTML5 : il leur faut une indication de la part de la (ou du) webmestre pour savoir quel est le niveau de compatibilité HTML souhaité. Cela est possible depuis SPIP 3.0 par l'apparition d'une nouvelle option de configuration.</p>
<dl class='spip_document_2521 spip_documents spip_documents_center'>
<dt><img src='http://www.spip.net/local/cache-vignettes/L500xH315/conf_html5-2b18a.png' width='500' height='315' alt='PNG - 56.1 ko' style='' /></dt>
<dt class='crayon document-titre-2521 spip_doc_titre' style='width:350px;'><strong>Configuration HTML5</strong></dt>
<dd class='crayon document-descriptif-2521 spip_doc_descriptif' style='width:350px;'>Zone de configuration dans SPIP pour autoriser ou non l'utilisation de HTML5.
</dd>
</dl>
<p>La balise <code class='spip_code' dir='ltr'>#HTML5</code> permet de tenir compte de ce choix :</p>
<ul class="spip"><li> Si le HTML5 est autorisé, la balise renvoie un résultat non-vide (espace)</li><li> Si la configuration reste sur HTML4 (valeur par défaut), la balise renvoie un résultat vide. Sur les versions de SPIP inférieures à SPIP 3.0, la balise est inconnue, et renverra donc également un résultat vide. Il est donc possible de l'utiliser n'importe où, quelle que soit la version de SPIP visée : les sites sous SPIP avant 2.2 seront juste considérés comme étant en HTML4.</li></ul><h3 class="spip">Exemples d'utilisation</h3>
<p>Par exemple, un plugin ou un squelette qui génère une zone de recherche dans un formulaire pourra utiliser la balise de la manière suivante :</p>
<div class="coloration_code"><div class="spip_xml cadre spip_cadre"><div class="xml"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #009900;"><span style="color: #000000; font-weight: bold;"><input</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"[(#HTML5|?{search,text})] ... /></span></span></div></li>
</ol></div></div></div>
<p>Ce code génèrera, si le HTML5 est activé dans la configuration :</p>
<div class="coloration_code"><div class="spip_xml cadre spip_cadre"><div class="xml"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #009900;"><span style="color: #000000; font-weight: bold;"><input</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"search"</span> ... <span style="color: #000000; font-weight: bold;">/></span></span></div></li>
</ol></div></div></div>
<p>et dans le cas contraire :</p>
<div class="coloration_code"><div class="spip_xml cadre spip_cadre"><div class="xml"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #009900;"><span style="color: #000000; font-weight: bold;"><input</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"text"</span> ... <span style="color: #000000; font-weight: bold;">/></span></span></div></li>
</ol></div></div></div>
<p>Autre exemple : définition d'une zone de saisie de formulaire comme obligatoire :</p>
<div class="coloration_code"><div class="spip_xml cadre spip_cadre"><div class="xml"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #009900;"><span style="color: #000000; font-weight: bold;"><input</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"text"</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>#HTML5<span style="color: #66cc66;">&#41;</span><span style="color: #000066;">required</span>=<span style="color: #ff0000;">"required"</span><span style="color: #66cc66;">&#93;</span> ... <span style="color: #000000; font-weight: bold;">/></span></span></div></li>
</ol></div></div></div>
<p>Le résultat sera donc l'un ou l'autre de ceux-ci suivant la configuration :</p>
<div class="coloration_code"><div class="spip_xml cadre spip_cadre"><div class="xml"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #009900;"><span style="color: #000000; font-weight: bold;"><input</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"text"</span> <span style="color: #000066;">required</span>=<span style="color: #ff0000;">"required"</span> ... <span style="color: #000000; font-weight: bold;">/></span></span></div></li>
</ol></div></div></div><div class="coloration_code"><div class="spip_xml cadre spip_cadre"><div class="xml"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #009900;"><span style="color: #000000; font-weight: bold;"><input</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"text"</span> ... <span style="color: #000000; font-weight: bold;">/></span></span></div></li>
</ol></div></div></div><h3 class="spip">Support par les navigateurs</h3>
<p>Bien sûr, comme toujours en développement web, n'oubliez pas de vérifier quel est le comportement des navigateurs qui ne connaissent pas les balises HTML et attributs que vous souhaitez utiliser.</p></div>
		
		<img src="http://feeds.feedburner.com/~r/Spip/~4/BXBeBDM-DnY" height="1" width="1"/>]]></content:encoded>


		

	<feedburner:origLink>http://www.spip.net/fr_article5057.html</feedburner:origLink></item>
<item xml:lang="fr">
		<title>Formulaires CVT en plusieurs pages</title>
		<link>http://feedproxy.google.com/~r/Spip/~3/_0ejQvV3fug/fr_article5386.html</link>
		<guid isPermaLink="false">http://www.spip.net/fr_article5386.html</guid>
		<dc:date>2012-05-19T09:31:09Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>JLuc</dc:creator>


		<dc:subject>Formulaires CVT</dc:subject>
		<dc:subject>SPIP 3.0</dc:subject>

		<description>&lt;p&gt;SPIP 3 introduit la possibilité de créer un formulaire composé de plusieurs pages de saisies avec validation de la saisie au fur de chaque page, et un seul traitement final&lt;span class="spip_note_ref"&gt; [&lt;a href='#nb1' class='spip_note' rel='footnote' title='Cette fonctionnalité est également accessible pour SPIP 2 mais nécessite (...)' id='nh1'&gt;1&lt;/a&gt;]&lt;/span&gt;.&lt;/p&gt;

-
&lt;a href="http://www.spip.net/fr_rubrique522.html" rel="directory"&gt;Interactivité&lt;/a&gt;

/ 
&lt;a href="http://www.spip.net/@multifrformulairescvtencvtformsesformularioscvtcaformulariscvtmulti" rel="tag"&gt;Formulaires CVT&lt;/a&gt;, 
&lt;a href="http://www.spip.net/@spip30" rel="tag"&gt;SPIP 3.0&lt;/a&gt;

		</description>


 <content:encoded><![CDATA[<div class='rss_chapo'><p>Les formulaires multi-étapes (ou multi-pages) sont une variation des formulaires CVT qui permet d'enchainer plusieurs pages de saisies, avec une validation (vérification) intermédiaire de chacune de ces pages et un traitement final qui permet de prendre en compte toutes les valeurs saisies en une seule fois.</p></div>
		<div class='rss_texte'><p>Il est nécessaire d'être déjà familier avec <a href="http://www.spip.net/fr_article3796.html" class='spip_in'>les formulaires CVT</a> pour créer un formulaire CVT en plusieurs pages.</p> <p>Nous allons voir comment construire facilement un formulaire d'inscription en 3 pages distinctes, SPIP prenant en charge la partie compliquée qui consiste à mémoriser les données déja saisies pour le traitement final, et à permettre la navigation entre les pages.</p>
<h3 class="spip">Les squelettes de chaque page</h3>
<p>Chaque page du formulaire se présente comme un formulaire complet (avec un bouton de validation qui sert à passer à l'étape suivante).</p> <p>Chacune des étape est numérotée, à partir de 1, et décrite par un fichier squelette indépendant qui implémente un formulaire autonome pour les saisies de cette page.</p> <p>Pour l'étape 1, le squelette est <code class='spip_code' dir='ltr'>formulaires/inscription.html</code>.<br class='manualbr' />Pour l'étape 2, le squelette est <code class='spip_code' dir='ltr'>formulaires/inscription_2.html</code>.<br class='manualbr' />Pour l'étape 3, le squelette est <code class='spip_code' dir='ltr'>formulaires/inscription_3.html</code>.</p> <p>Voici par exemple à quoi ressemble la première page de notre formulaire :</p>
<div class="coloration_code"><div class="spip_spip2 cadre spip_cadre"><div class="spip2"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><div class="formulaire_spip"></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> <span style="color: #D05000;">[</span><p class="reponse_formulaire reponse_formulaire_ok"><span style="color: #D05000;">(</span><span style="color: #D05000;">#ENV</span><span style="color: #FF4E00;">*</span><span style="color: #74B900;">{message_ok}</span><span style="color: #D05000;">)</span></p><span style="color: #D05000;">]</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> <span style="color: #D05000;">[</span><p class="reponse_formulaire reponse_formulaire_erreur"><span style="color: #D05000;">(</span><span style="color: #D05000;">#ENV</span><span style="color: #FF4E00;">*</span><span style="color: #74B900;">{message_erreur}</span><span style="color: #D05000;">)</span></p><span style="color: #D05000;">]</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> [(<span style="color: #D05000;">#ENV</span><span style="color: #74B900;">{editable}</span>)</div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> <form method='post' action='<span style="color: #D05000;">#ENV</span><span style="color: #74B900;">{action}</span>'><div></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> <span style="color: #D05000;">[</span><span style="color: #D05000;">(</span><span style="color: #D05000;">#REM</span><span style="color: #D05000;">)</span> les hidden qui declencheront le service du formulaire parametre : url d'action <span style="color: #D05000;">]</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> <span style="color: #D05000;">#ACTION_FORMULAIRE</span><span style="color: #74B900;">{<span style="color: #D05000;">#ENV</span>{action},<span style="color: #D05000;">#FORM</span>}</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> </div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> <span style="color: #808080; font-style: italic;"><!-- Ici les saisies de l'étape 1, directement en HTML. </span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #808080; font-style: italic;"> Elles pourraient aussi être générées par le plugin SAISIES --></span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> <label>Votre email</label></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> <input type='text' name='email' value='<span style="color: #D05000;">#ENV</span><span style="color: #74B900;">{email}</span>' /> </div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> <input type="submit" class="submit" value="<span style="color: #C90"><:pass_ok:></span>" /></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> </div></form></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> ]</div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""></div></div></li>
</ol></div></div><div class='cadre_download' style='text-align: right;'> <a href='http://www.spip.net/local/cache-code/60289f0c79086c8492487746ea635098.txt' style='font-family: verdana, arial, sans; font-weight: bold; font-style: normal;'>Télécharger</a></div></div>
<p>À l'intérieur de chaque squelette, <code class='spip_code' dir='ltr'>#ENV{_etape}</code> renvoie le n° de l'étape, et <code class='spip_code' dir='ltr'>#ENV{_etapes}</code> renvoie le nombre total d'étapes de saisie. Cela permet par exemple d'afficher un état de l'avancement de la saisie par rapport au nombre total de pages de saisies :</p>
<div class="coloration_code"><div class="spip_spip2 cadre spip_cadre"><div class="spip2"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><div class="formulaire_spip formulaire_inscription formulaire_<span style="color: #D05000;">#FORM</span> formulaire_<span style="color: #D05000;">#FORM_</span><span style="color: #D05000;">#ENV</span><span style="color: #74B900;">{_etape}</span>"></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""> <h3>Inscription <span style="color: #D05000;">#ENV</span><span style="color: #74B900;">{_etape}</span> / <span style="color: #D05000;">#ENV</span><span style="color: #74B900;">{_etapes}</span> : indiquez votre email</h3></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="">... </div></li>
</ol></div></div><div class='cadre_download' style='text-align: right;'> <a href='http://www.spip.net/local/cache-code/63f0c13ae1d4aef317b01fa07d0a73b1.txt' style='font-family: verdana, arial, sans; font-weight: bold; font-style: normal;'>Télécharger</a></div></div>
<p>A chaque page, <code class='spip_code' dir='ltr'>#ENV</code> contient toutes les valeurs déjà saisies lors des étapes précédentes. Ainsi, si vous voulez proposer une valeur par défaut qui dépend d'une saisie précédente, il suffit d'utiliser celle-ci pour pré-remplir votre saisie.</p> <p>Sur chaque page, il est aussi possible de proposer un bouton qui renvoie vers une autre étape (par exemple pour faire un bouton de retour à l'étape précédente). Il suffit pour cela de donner au bouton l'attribut <code class='spip_code' dir='ltr'>name</code> avec la valeur <code class='spip_code' dir='ltr'>_retour_etape_n</code>, <code class='spip_code' dir='ltr'>n</code> désignant le numéro de l'étape visée :</p> <textarea readonly='readonly' cols='40' rows='5' class='spip_cadre' dir='ltr'><p class="boutons"> <input type="submit" class="submit" name="_retour_etape_2" value="<:retour:>" /> </p></textarea>
<p>Il est possible que cette étape soit une étape en avant, mais attention : dans tous les cas l'utilisateur ne pourra passer à une étape n que si la saisie des étapes précédentes est correcte et sans erreur ! Dans le cas contraire, c'est la première page avec des erreurs qui lui sera présentée.</p>
<h3 class="spip">Charger et déclarer les étapes de saisie</h3>
<p>La déclaration des étapes ou pages de saisies se fait dans la fonction charger() de votre formulaire CVT.</p> <p>La fonction charger() est identique à celle d'un formulaire CVT conventionnel : elle doit retourner un tableau de tous les champs qui seront saisis dans l'ensemble du formulaire (donc toutes étapes confondues, comme si il n'y avait qu'une seule page de saisie).</p> <p>Mais en plus, elle doit déclarer que le formulaire comporte plusieurs pages. Cela se fait en renvoyant en plus une valeur '_etapes' qui désigne le nombre d'étapes de saisies.</p> <p>Dans notre exemple :</p>
<div class="coloration_code"><div class="spip_php code"><span style="color: #000000; font-weight: bold;">function</span> formulaires_inscription_charger_dist<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">{</span><br /> <span style="color: #b1b100;">return</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a> <span style="color: #009900;">&#40;</span><br /> <span style="color: #0000ff;">'email'</span> <span style="color: #339933;">=></span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">// etape 1</span><br /> <span style="color: #0000ff;">'nom'</span> <span style="color: #339933;">=></span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">// etape 2</span><br /> <span style="color: #0000ff;">'prenom'</span> <span style="color: #339933;">=></span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span><br /> <span style="color: #0000ff;">'semaine'</span> <span style="color: #339933;">=></span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">// étape 3</span><br /> <span style="color: #0000ff;">'_etapes'</span> <span style="color: #339933;">=></span> <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">}</span></div><div class='code_download' style='text-align: right;'> <a href='http://www.spip.net/local/cache-code/6adb661f9f50f167bfc6503f3fbec615.txt' style='font-family: verdana, arial, sans; font-weight: bold; font-style: normal;'>Télécharger</a></div></div>
<p>C'est cette valeur _etapes qui va déclencher la prise en charge par SPIP des différentes pages préparées ci-dessus.</p>
<h3 class="spip"> Vérifier la saisie à chaque étape</h3>
<p>La vérification de la saisie présente ici une particularité. Au lieu d'avoir une seule fonction verifier() comme dans un formulaire CVT conventionnel, il va falloir fournir ici une fonction verifier() par page de saisie. Celles-ci sont numérotées à partir de 1 comme pour les squelettes des différentes pages.</p> <p><code class='spip_code' dir='ltr'>formulaires_inscription_verifier_1_dist</code> vérifie les saisies de l'étape 1 uniquement.<br class='manualbr' /><code class='spip_code' dir='ltr'>formulaires_inscription_verifier_2_dist</code> vérifie les saisies de l'étape 2.<br class='manualbr' /><code class='spip_code' dir='ltr'>formulaires_inscription_verifier_3_dist</code> vérifie les saisies de l'étape 3.<br class='manualbr' />etc.</p> <p>A l'intérieur de ces fonctions, l'appel à <code class='spip_code' dir='ltr'>_request</code> permet d'accéder aux valeurs saisies depuis l'étape 1 jusqu'à l'étape courante.</p> <p>Le numéro d'étape courante et le nombre totale d'étapes sont également accessible par <code class='spip_code' dir='ltr'>request('_etape')</code> et par <code class='spip_code' dir='ltr'>request('_etapes')</code>, si nécessaire, pour mutualiser du code par exemple.</p> <p>Après chaque page <code class='spip_code' dir='ltr'>n</code>, SPIP appelle les fonctions de vérification des étapes <code class='spip_code' dir='ltr'>1</code> à <code class='spip_code' dir='ltr'>n</code> pour vérifier l'absence de régression dans la validation (qui pourrait être due à une erreur ou à une tentative de fraude par l'utilisateur). En cas d'erreur, l'utilisateur est automatiquement renvoyé sur la première page dont la saisie n'est pas correcte.</p> <p>En cas de succès, SPIP passe à l'étape suivante, sauf si l'utilisateur est arrivé à la dernière page, auquel cas SPIP appelle la fonction <code class='spip_code' dir='ltr'>traiter()</code>.</p>
<h3 class="spip">Traiter la saisie</h3>
<p>La fonction de traitement des saisies du formulaire n'est appelée que lorsque toutes les pages ont été saisies sans erreur.</p> <p>Elle peut accéder à l'ensemble des saisies avec la fonction <code class='spip_code' dir='ltr'>_request</code> comme si le formulaire avait été saisi en une seule fois.</p> <p>La fonction de traitement est donc tout à fait identique à celle d'un formulaire en une page et se nomme classiquement (ici <code class='spip_code' dir='ltr'>formulaires_inscription_traiter_dist()</code>).</p>
<h3 class="spip">Sans oublier...</h3>
<p>- Ce formulaire ainsi construit bénéficie de tous les avantages des formulaires CVT. Il suffit donc de l'encapsuler dans une <code class='spip_code' dir='ltr'><div class='ajax'></code> pour qu'il soit automatiqent pris en charge et permette la saisie multi-page en ajax.</p> <p>- Il est possible d'appeler le formulaire en commençant directement à l'étape 5, par exemple. Pour cela, il suffit de passer le paramètre "_etape=5" dans l'environnement (dans l'url par exemple).<br class='manualbr' />Dans ce cas, les vérifications des 4 pages précédentes sont effectuées et en cas de validation, l'étape 5 est affichée. Sinon c'est la première étape qui présente une erreur qui est affichée.</p></div>
		<hr />
		<div class='rss_notes'><div id='nb1'>
<p><span class="spip_note_ref">[<a href='#nh1' class='spip_note' title='Notes 1' rev='footnote'>1</a>] </span>Cette fonctionnalité est également accessible pour SPIP 2 mais nécessite l'activation du <a href="http://files.spip.org/spip-zone/#cvt-multi-etapes" class='spip_out' rel='external'>plugin cvt-multi-etapes</a></p>
</div></div>
		
		<img src="http://feeds.feedburner.com/~r/Spip/~4/_0ejQvV3fug" height="1" width="1"/>]]></content:encoded>


		

	<feedburner:origLink>http://www.spip.net/fr_article5386.html</feedburner:origLink></item>
<item xml:lang="fr">
		<title>Formulaire CVT avec sauvegarde automatique</title>
		<link>http://feedproxy.google.com/~r/Spip/~3/YQTyuE_1aWg/fr_article5428.html</link>
		<guid isPermaLink="false">http://www.spip.net/fr_article5428.html</guid>
		<dc:date>2012-05-19T09:31:05Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>cerdic</dc:creator>


		<dc:subject>Formulaires CVT</dc:subject>
		<dc:subject>SPIP 3.0</dc:subject>

		<description>&lt;p&gt;SPIP 3.0 introduit la prise en charge de la sauvegarde automatique de la saisie de l'utilisateur.&lt;/p&gt;

-
&lt;a href="http://www.spip.net/fr_rubrique522.html" rel="directory"&gt;Interactivité&lt;/a&gt;

/ 
&lt;a href="http://www.spip.net/@multifrformulairescvtencvtformsesformularioscvtcaformulariscvtmulti" rel="tag"&gt;Formulaires CVT&lt;/a&gt;, 
&lt;a href="http://www.spip.net/@spip30" rel="tag"&gt;SPIP 3.0&lt;/a&gt;

		</description>


 <content:encoded><![CDATA[<div class='rss_texte'><p>Pour éviter que les utilisateurs ne perdent le bénéfice de leur saisie en cas de perte de connexion ou de fausse manipulation, il est possible d'activer une fonction de sauvegarde automatisée dans les formulaires CVT.</p>
<h3 class="spip">Activer la fonction</h3>
<p>Pour activer la prise en charge, il suffit que la fonction charger() du formulaire renvoie un identifiant unique qui désigne le formulaire.</p> <p>Il y aura une sauvegarde différente par identifiant unique (et par formulaire), celui-ci doit donc dépendre du contexte de la saisie. Par exemple sur un formulaire de forum en réponse à un article on choisira de passer comme identifiant l'id_article de l'article auquel on répond.</p> <p>Cet identifiant peut être un entier, une chaine ou un tableau, et doit être envoyé dans le champ '_autosave_id' :</p>
<div class="coloration_code"><div class="spip_php cadre spip_cadre"><div class="php"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #000000; font-weight: bold;">function</span> formulaires_repondre_article_charger_dist<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id_article</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">{</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #339933;">...</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #b1b100;">return</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #339933;">...,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #0000ff;">'_autosave_id'</span> <span style="color: #339933;">=></span> <span style="color: #000088;">$id_article</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #009900;">}</span></div></li>
</ol></div></div><div class='cadre_download' style='text-align: right;'> <a href='http://www.spip.net/local/cache-code/3953aaa0869e8f42a324063c8381c5ef.txt' style='font-family: verdana, arial, sans; font-weight: bold; font-style: normal;'>Télécharger</a></div></div><h3 class="spip">Ou sont sauvegardées les données ?</h3>
<p>Lorsqu'on active cette fonction, le formulaire va envoyer à chaque modification de saisie une requête à SPIP avec la liste de tous les champs saisis. SPIP va alors stocker cette information dans la session de l'utilisateur, sur le serveur.</p> <p>Lorsque la saisie est complète et que l'utilisateur valide le formulaire, SPIP va alors vider cette sauvegarde (lors du traitement du formulaire).</p> <p>Mais si l'utilisateur rencontre une erreur ou un problème et oublie de valider le formulaire, la sauvegarde est conservée 72H. Si l'utilisateur revient sur le même formulaire, il va retrouver le formulaire pré-rempli avec toutes les informations qu'il avait saisi auparavant.</p>
<h3 class="spip">De la vie privée ...</h3>
<p>Attention cependant à ne pas utiliser cette sauvegarde automatique dans un formulaire qui collecte des données personnelles dans une session anonyme.</p> <p>Si l'utilisateur est sur un poste de consultation public et ne valide pas, ses données seront alors disponibles pour quiconque revient sur la même page avec son poste de consultation.</p> <p>Par ailleurs, il est possible de personnaliser la durée de 72H de conservation des données saisies en précisant dans le fichier <code class='spip_code' dir='ltr'>mes_options.php</code> par exemple (pour une durée de 24h) :</p>
<div class="coloration_code"><div class="spip_php cadre spip_cadre"><div class="php"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><a href="http://www.php.net/define"><span style="color: #990000;">define</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'_AUTOSAVE_GB_DELAY'</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">24</span><span style="color: #339933;">*</span><span style="color: #cc66cc;">3600</span><span style="color: #009900;">&#41;</span></div></li>
</ol></div></div></div></div>
		
		<img src="http://feeds.feedburner.com/~r/Spip/~4/YQTyuE_1aWg" height="1" width="1"/>]]></content:encoded>


		

	<feedburner:origLink>http://www.spip.net/fr_article5428.html</feedburner:origLink></item>
<item xml:lang="fr">
		<title>{tri} et #TRI dans les boucles</title>
		<link>http://feedproxy.google.com/~r/Spip/~3/3h6XhUH5DOI/fr_article5429.html</link>
		<guid isPermaLink="false">http://www.spip.net/fr_article5429.html</guid>
		<dc:date>2012-05-19T09:31:01Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>cerdic</dc:creator>


		<dc:subject>SPIP 3.0</dc:subject>

		<description>
&lt;p&gt;SPIP 3.0 introduit un critère et une balise qui permettent de faire facilement des listes triables.&lt;br class='autobr' /&gt;
Le critère tri simplifie la réalisation de listes triables de la même façon que le critère pagination simplifie la réalisation de listes paginées.&lt;br class='autobr' /&gt;
Dans une boucle simple, il permet de définir le critère de tri en lui indiquant en argument le champ à utiliser par défaut :&lt;br class='autobr' /&gt;
Jusque là rien de nouveau par rapport au critère par. Mais tri peut être associé à la balise #TRI qui permet de générer un lien pour (...)&lt;/p&gt;


-
&lt;a href="http://www.spip.net/fr_rubrique522.html" rel="directory"&gt;Interactivité&lt;/a&gt;

/ 
&lt;a href="http://www.spip.net/@spip30" rel="tag"&gt;SPIP 3.0&lt;/a&gt;

		</description>


 <content:encoded><![CDATA[<div class='rss_chapo'><p>SPIP 3.0 introduit un critère et une balise qui permettent de faire facilement des listes triables.</p></div>
		<div class='rss_texte'><p>Le critère <code class='spip_code' dir='ltr'>{tri}</code> simplifie la réalisation de listes triables de la même façon que le critère <code class='spip_code' dir='ltr'>{pagination}</code> simplifie la réalisation de listes paginées.</p> <p>Dans une boucle simple, il permet de définir le critère de tri en lui indiquant en argument le champ à utiliser par défaut :</p>
<div class="coloration_code"><div class="spip_spip2 cadre spip_cadre"><div class="spip2"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #1DA3DD;"><BOUCLE_art</span><span style="color: #527EE0;">(ARTICLES)</span><span style="color: #984CFF;"><span style="">{tri titre}</span></span><span style="color: #1DA3DD;">></span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #1DA3DD;"></BOUCLE_art></span></div></li>
</ol></div></div><div class='cadre_download' style='text-align: right;'> <a href='http://www.spip.net/local/cache-code/efb0f385375f5321f15bf7bf377ca8f8.txt' style='font-family: verdana, arial, sans; font-weight: bold; font-style: normal;'>Télécharger</a></div></div>
<p>Jusque là rien de nouveau par rapport au critère <code class='spip_code' dir='ltr'>{par}</code>. Mais <code class='spip_code' dir='ltr'>{tri}</code> peut être associé à la balise <code class='spip_code' dir='ltr'>#TRI</code> qui permet de générer un lien pour changer le critère de tri. La balise <code class='spip_code' dir='ltr'>#TRI</code> prend en premier argument le champ de tri, et en second argument le libellé du lien clicable pour utiliser ce champ pour le tri :</p>
<div class="coloration_code"><div class="spip_spip2 cadre spip_cadre"><div class="spip2"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #1DA3DD;"><B_art></span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><p><span style="color: #D05000;">#TRI</span><span style="color: #74B900;">{titre,'Trier par titre'}</span> | <span style="color: #D05000;">#TRI</span><span style="color: #74B900;">{date,'Trier par date'}</span> | </div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #D05000;">#TRI</span><span style="color: #74B900;">{date_redac,'Trier par date de rédaction'}</span></p></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #1DA3DD;"><BOUCLE_art</span><span style="color: #527EE0;">(ARTICLES)</span><span style="color: #984CFF;"><span style="">{tri titre}</span></span><span style="color: #1DA3DD;">></span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #1DA3DD;"></BOUCLE_art></span></div></li>
</ol></div></div><div class='cadre_download' style='text-align: right;'> <a href='http://www.spip.net/local/cache-code/d851246cd2eee8961ea1009dbf554016.txt' style='font-family: verdana, arial, sans; font-weight: bold; font-style: normal;'>Télécharger</a></div></div>
<p>Ce faisant l'utilisateur se voit proposer un menu pour modifier le tri de la boucle. Le tri actuellement utilisé est exposé en gras et non clicable, et les tris non utilisés sont des liens clicables.</p> <p>Si la boucle est dans une inclusion ajax, il suffit de renseigner la classe ajax en troisième argument de la balise <code class='spip_code' dir='ltr'>#TRI</code> pour que les liens se comportent avec un rechargement partiel de la page :</p>
<div class="coloration_code"><div class="spip_spip2 cadre spip_cadre"><div class="spip2"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #1DA3DD;"><B_art></span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><p><span style="color: #D05000;">#TRI</span><span style="color: #74B900;">{titre,'Trier par titre',ajax}</span> | <span style="color: #D05000;">#TRI</span><span style="color: #74B900;">{date,'Trier par date',ajax}</span> | </div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #D05000;">#TRI</span><span style="color: #74B900;">{date_redac,'Trier par date de rédaction',ajax}</span></p></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #1DA3DD;"><BOUCLE_art</span><span style="color: #527EE0;">(ARTICLES)</span><span style="color: #984CFF;"><span style="">{tri titre}</span></span><span style="color: #1DA3DD;">></span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #1DA3DD;"></BOUCLE_art></span></div></li>
</ol></div></div><div class='cadre_download' style='text-align: right;'> <a href='http://www.spip.net/local/cache-code/1d1323477cd512ef2a08b8e5303c6c9a.txt' style='font-family: verdana, arial, sans; font-weight: bold; font-style: normal;'>Télécharger</a></div></div>
<p>Le critère <code class='spip_code' dir='ltr'>{tri}</code> permet également d'indiquer le sens du tri par défaut en second argument. Il faut indiquer la valeur <code class='spip_code' dir='ltr'>direct</code> ou <code class='spip_code' dir='ltr'>1</code> pour indiquer un tri croissant par défaut, et <code class='spip_code' dir='ltr'>inverse</code> ou <code class='spip_code' dir='ltr'>-1</code> pour un tri décroissant par défaut :</p>
<div class="coloration_code"><div class="spip_spip2 cadre spip_cadre"><div class="spip2"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #1DA3DD;"><B_art></span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><p><span style="color: #D05000;">#TRI</span><span style="color: #74B900;">{titre,'Trier par titre'}</span> | <span style="color: #D05000;">#TRI</span><span style="color: #74B900;">{date,'Trier par date'}</span> | </div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #D05000;">#TRI</span><span style="color: #74B900;">{date_redac,'Trier par date de rédaction'}</span></p></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #1DA3DD;"><BOUCLE_art</span><span style="color: #527EE0;">(ARTICLES)</span><span style="color: #984CFF;"><span style="">{tri date,-1}</span></span><span style="color: #1DA3DD;">></span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #1DA3DD;"></BOUCLE_art></span></div></li>
</ol></div></div><div class='cadre_download' style='text-align: right;'> <a href='http://www.spip.net/local/cache-code/6bee962d3e3449d7610e7001883ee34c.txt' style='font-family: verdana, arial, sans; font-weight: bold; font-style: normal;'>Télécharger</a></div></div>
<p>Par ailleurs il est aussi possible de proposer le choix du sens de tri. Cela se fait en passant <code class='spip_code' dir='ltr'>></code> pour un tri croissant et <code class='spip_code' dir='ltr'><</code> pour un tri décroissant en premier argument de la balise <code class='spip_code' dir='ltr'>#TRI</code> :</p>
<div class="coloration_code"><div class="spip_spip2 cadre spip_cadre"><div class="spip2"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #1DA3DD;"><B_art></span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><p><span style="color: #D05000;">#TRI</span><span style="color: #74B900;">{>,'Tri croissant',ajax}</span> | <span style="color: #D05000;">#TRI</span><span style="color: #74B900;">{>,'Tri décroissant',ajax}</span> | <span style="color: #D05000;">#TRI</span><span style="color: #74B900;">{titre,'Trier par titre',ajax}</span> | <span style="color: #D05000;">#TRI</span><span style="color: #74B900;">{date,'Trier par date',ajax}</span> | </div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #D05000;">#TRI</span><span style="color: #74B900;">{date_redac,'Trier par date de rédaction',ajax}</span></p></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #1DA3DD;"><BOUCLE_art</span><span style="color: #527EE0;">(ARTICLES)</span><span style="color: #984CFF;"><span style="">{tri titre}</span></span><span style="color: #1DA3DD;">></span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #1DA3DD;"></BOUCLE_art></span></div></li>
</ol></div></div><div class='cadre_download' style='text-align: right;'> <a href='http://www.spip.net/local/cache-code/59827ca97fee16bd40a13e5c9f7959b8.txt' style='font-family: verdana, arial, sans; font-weight: bold; font-style: normal;'>Télécharger</a></div></div>
<p>Cela dit, plutôt que de proposer des boutons de tri systématique, une alternative est possible : adapter automatiquement le sens du tri à la colonne utilisée pour le tri. Cela se fait en passant en second argument de la balise tri un tableau avec le sens par défaut pour chaque colonne :</p>
<div class="coloration_code"><div class="spip_spip2 cadre spip_cadre"><div class="spip2"><ol><li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #D05000;">#SET</span><span style="color: #74B900;">{defaut_tri,<span style="color: #D05000;">#ARRAY</span>{</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #74B900;">tri,1,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #74B900;">date,-1,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #74B900;">date_redac,-1</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #74B900;">}}</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #1DA3DD;"><B_art></span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><p><span style="color: #D05000;">#TRI</span><span style="color: #74B900;">{titre,'Trier par titre',ajax}</span> | <span style="color: #D05000;">#TRI</span><span style="color: #74B900;">{date,'Trier par date',ajax}</span> | </div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #D05000;">#TRI</span><span style="color: #74B900;">{date_redac,'Trier par date de rédaction',ajax}</span></p></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #1DA3DD;"><BOUCLE_art</span><span style="color: #527EE0;">(ARTICLES)</span><span style="color: #984CFF;"><span style="">{tri titre,<span style="color: #D05000;">#GET</span><span style="color: #74B900;">{defaut_tri}</span>}</span></span><span style="color: #1DA3DD;">></span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style=""><span style="color: #1DA3DD;"></BOUCLE_art></span></div></li>
</ol></div></div><div class='cadre_download' style='text-align: right;'> <a href='http://www.spip.net/local/cache-code/59e95b8aef2fdf0f208b0eb311bf8768.txt' style='font-family: verdana, arial, sans; font-weight: bold; font-style: normal;'>Télécharger</a></div></div>
<p>Ainsi quand l'utilisateur choisira le tri par titre, celui-ci sera dans un ordre croissant. Mais quand il choisira la date ou la date de rédaction, le tri se fera dans un ordre décroissant.</p></div>
		
		<img src="http://feeds.feedburner.com/~r/Spip/~4/3h6XhUH5DOI" height="1" width="1"/>]]></content:encoded>


		

	<feedburner:origLink>http://www.spip.net/fr_article5429.html</feedburner:origLink></item>
<item xml:lang="fr">
		<title>Les itérateurs de SPIP</title>
		<link>http://feedproxy.google.com/~r/Spip/~3/eLwMJDLKL5M/fr_article5444.html</link>
		<guid isPermaLink="false">http://www.spip.net/fr_article5444.html</guid>
		<dc:date>2012-05-19T09:30:50Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>Fil, Matthieu Marcillaud</dc:creator>


		<dc:subject>SPIP 3.0</dc:subject>

		<description>
&lt;p&gt;Nous sommes en train de développer dans SPIP une notion générale de boucle, basée sur les itérateurs de PHP.&lt;br class='autobr' /&gt;
Ces boucles ne portent plus exclusivement sur des requêtes SQL, mais peuvent tourner sur toutes sortes de listes de données. Par exemple :&lt;br class='autobr' /&gt; un tableau de données produit par une fonction quelconque&lt;br class='autobr' /&gt; le contenu d'un fichier local au format XML, CSV, JSON, YAML, etc.&lt;br class='autobr' /&gt; une liste de fichiers dans un répertoire du serveur&lt;br class='autobr' /&gt; une requête sur un webservice&lt;br class='autobr' /&gt; etc (LDAP...).&lt;br class='autobr' /&gt;
Les boucles SQL&lt;br class='autobr' /&gt;
Sans (...)&lt;/p&gt;


-
&lt;a href="http://www.spip.net/fr_rubrique702.html" rel="directory"&gt;Les itérateurs&lt;/a&gt;

/ 
&lt;a href="http://www.spip.net/@spip30" rel="tag"&gt;SPIP 3.0&lt;/a&gt;

		</description>


 <content:encoded><![CDATA[<div class='rss_chapo'><p>Nous sommes en train de développer dans SPIP une notion générale de boucle, basée sur les itérateurs de PHP.</p></div>
		<div class='rss_texte'><p>Ces boucles ne portent plus exclusivement sur des requêtes SQL, mais peuvent tourner sur toutes sortes de listes de données. Par exemple :<br />— un tableau de données produit par une fonction quelconque<br />— le contenu d'un fichier local au format XML, CSV, JSON, YAML, etc.<br />— une liste de fichiers dans un répertoire du serveur<br />— une requête sur un webservice<br />— etc (LDAP...).</p>
<h3 class="spip">Les boucles SQL</h3>
<p>Sans surprise, l'itérateur classique de SPIP s'appelle SQL. Il exécute la requête telle que SPIP l'a calculée, et sait parcourir la liste de résultats pour les envoyer à la boucle.</p>
<h3 class="spip">La boucle <code class='spip_code' dir='ltr'>(DATA)</code></h3>
<p>C'est une boucle capable d'itérer n'importe quel tableau de données. Sa syntaxe de base est la suivante :</p>
<div style='text-align: left;' class='spip_code' dir='ltr'><code><BOUCLE(DATA) {source ...}> #BALISES </BOUCLE></code></div>
<p>Le critère <code class='spip_code' dir='ltr'>{source format, données}</code> définit les données sur lesquelles la boucle va itérer.</p> <p>La définition d'une source de données nécessite deux éléments :</p> <p>— <strong>La partie <code class='spip_code' dir='ltr'>données</code></strong> : cet élément peut être de plusieurs natures :<br />- un tableau de données, par exemple <code class='spip_code' dir='ltr'>#ENV*</code><br />- le chemin d'un fichier sur le disque dur, ex : <code class='spip_code' dir='ltr'>sources/definitions.csv</code><br />- l'URL d'un fichier ou d'un webservice, ex : <code class='spip_code' dir='ltr'>http://per.sonn.es/bases/phobia.fr.yaml</code><br />- ou encore, une chaîne quelconque que le format saura transformer en tableau de données, ex : <code class='spip_code' dir='ltr'>"select * from flickr.photos.search where text='spip'"</code></p> <p>— <strong>La partie <code class='spip_code' dir='ltr'>format</code></strong> est à prendre dans la liste ci-dessous :<br />- <code class='spip_code' dir='ltr'>table</code> (alias <code class='spip_code' dir='ltr'>array</code> ou <code class='spip_code' dir='ltr'>tableau</code>), pour un tableau déjà créé<br />- <code class='spip_code' dir='ltr'>csv</code>, <code class='spip_code' dir='ltr'>json</code>, <code class='spip_code' dir='ltr'>yaml</code> pour un fichier composé dans l'un de ces formats<br />- <code class='spip_code' dir='ltr'>file</code> pour boucler sur les lignes d'un fichier<br />- <code class='spip_code' dir='ltr'>glob</code> ou <code class='spip_code' dir='ltr'>pregfiles</code> pour boucler sur les fichiers d'un répertoire (et plus...)<br />- <code class='spip_code' dir='ltr'>rss</code> (alias <code class='spip_code' dir='ltr'>atom</code>) pour lire un flux de nouvelles<br />- <code class='spip_code' dir='ltr'>plugins</code> pour lister les plugins actifs sur le site<br />- <code class='spip_code' dir='ltr'>yql</code> pour envoyer une requête sur le webservice de Yahoo Query Language<br />- <code class='spip_code' dir='ltr'>sql</code> pour envoyer une requête brute au serveur SQL (utiliser <code class='spip_code' dir='ltr'>{source sql, connecteur:requete}</code> pour envoyer la requête sur une base externe)<br />- <code class='spip_code' dir='ltr'>ics</code> pour boucler sur des calendriers (nécessite le plugin <i>icalendar</i> : lire <a href="http://www.spip.net/fr_article5446.html" class='spip_in'>La boucle iCalendar</a>)<br />- etc.</p> <p>Tous ces formats sont déjà disponibles, et il est très aisé d'en ajouter un nouveau, en créant une simple fonction <code class='spip_code' dir='ltr'>inc_FORMAT_to_array($u)</code>. A titre d'exemple voici la fonction qui transforme un fichier JSON en tableau de données :</p>
<div style='text-align: left;' class='spip_code' dir='ltr'><code>function inc_json_to_array_dist($u) {<br /> if (is_array($json = json_decode($u))<br /> OR is_object($json))<br /> return (array) $json;<br />
}</code></div>
<p><i>A lire : <a href="http://www.spip.net/fr_article5443.html" class='spip_in'>Exemples de <code class='spip_code' dir='ltr'>BOUCLE(DATA)</code> </a>.</i></p>
<h3 class="spip">YQL — Yahoo Query Language</h3>
<p>YQL est un webservice permettant d'interroger de façon simple de nombreux sites comme google, twitter, flickr, etc. Avec la boucle <code class='spip_code' dir='ltr'>(DATA)</code>, SPIP facilite grandement son intégration sous forme de boucles : <i>Cf.</i> <a href="http://zzz.rezo.net/Exemples-de-boucles-YQL.html" class='spip_url spip_out' rel='external'>http://zzz.rezo.net/Exemples-de-bou...</a>.</p>
<h3 class="spip">Itérateurs PHP</h3>
<p>SPIP est capable d'utiliser les itérateurs PHP standards. Il convient de se reporter à leur documentation, qui est souvent très succincte, et de vérifier que les itérateurs en questions sont disponibles sur votre système.</p> <p>Notons, par exemple, <code class='spip_code' dir='ltr'>DirectoryIterator</code>, qui permet de lister les fichiers d'un répertoire :</p> <p>Boucle :</p>
<div style='text-align: left;' class='spip_code' dir='ltr'><code><pre><br />
<BOUCLE_ls(php:DirectoryIterator){args IMG/jpg/}<br /> {pagination 10}<br /> {valeur!==^\.}{valeur==\.jpg$}<br />
>[(#VAL{Y-m-d H:i:s}|date{#GETMTIME})] / #VALEUR<br />
</BOUCLE_ls><br />
</pre><br />
#PAGINATION<br />
</B_ls></code></div>
<p>Résultat :</p>
<blockquote class="spip">
<pre>2008-02-01 23:27:23 / arton2135.jpg
2008-08-21 11:12:58 / DSC03420.jpg
2008-08-21 11:13:11 / DSC03421.jpg
2009-08-27 11:20:11 / hash-1.jpg
2009-08-27 11:20:04 / hash.jpg</pre>
</blockquote>
<p>Il convient d'indiquer à SPIP qu'il s'agit d'un itérateur PHP, en indiquant <code class='spip_code' dir='ltr'>(php:...)</code> avant le nom de l'itérateur.</p> <p>Le critère <code class='spip_code' dir='ltr'>{args xx,yy}</code> définit les arguments que l'on va passer à l'itérateur lors de son initialisation. Pour <code class='spip_code' dir='ltr'>DirectoryIterator</code>, il s'agit du chemin du répertoire à lister.</p> <p>Les méthodes de cet itérateur (<i>cf.</i> <a href="http://php.net/manual/fr/class.directoryiterator.php" class='spip_url spip_out auto' rel='nofollow external'>http://php.net/manual/fr/class.directoryiterator.php</a>) sont disponibles sous forme de balises (ici, <code class='spip_code' dir='ltr'>#GETMTIME</code>).</p> <p><i>Remarque :</i> pour lister le contenu d'un répertoire, le format <code class='spip_code' dir='ltr'>glob</code> de la boucle <code class='spip_code' dir='ltr'>(DATA)</code> est sans doute plus facile à utiliser que cet itérateur PHP.<br class='manualbr' /></p>
<div style='text-align: left;' class='spip_code' dir='ltr'><code><BOUCLE_ls(DATA){source ls, IMG/jpg/*.jpg}<br />
{!par mtime}> ...</code></div><h3 class="spip"> Filtrage, tri, pagination, fusion </h3>
<p><strong>Filtres.</strong> Comme les boucles SQL, les boucles <code class='spip_code' dir='ltr'>(DATA)</code> peuvent être filtrées par des critères du type <code class='spip_code' dir='ltr'>{valeur=x}</code> ; les opérateurs disponibles sont <code class='spip_code' dir='ltr'>=</code>, <code class='spip_code' dir='ltr'>></code>, <code class='spip_code' dir='ltr'><</code>, <code class='spip_code' dir='ltr'>>=</code>, <code class='spip_code' dir='ltr'><=</code>, <code class='spip_code' dir='ltr'>==</code> (expression rationnelle) et <code class='spip_code' dir='ltr'>LIKE</code>.</p> <p>Cependant ce filtrage s'effectue non pas en amont lors de la requête, comme en SQL, mais en aval, sur le tableau de données initialement récupéré.</p> <p><strong>Tris.</strong> Les tris <code class='spip_code' dir='ltr'>{par xx}</code> sont également possibles, avec leur variante <code class='spip_code' dir='ltr'>{!par xx}</code> pour trier en ordre inverse.</p> <p><strong>Pagination.</strong> La pagination fonctionne normalement, ainsi que le critère offset/limit <code class='spip_code' dir='ltr'>{a,b}</code>.</p> <p><strong>Fusion.</strong> Le critère <code class='spip_code' dir='ltr'>{fusion /x/y}</code> fonctionne aussi. Par exemple, pour un fichier d'adresses au format CSV, si l'email est le champ n° 3, on pourra ne retenir qu'un seul enregistrement par email avec la boucle suivante :</p>
<div style='text-align: left;' class='spip_code' dir='ltr'><code> <BOUCLE_csv(DATA){source csv, adresses.csv} <br /> {fusion /3} <br /> {par /0}{'<br />'}> <br /> #VALEUR{0} : #VALEUR{3} <br /> </BOUCLE_csv> </code></div>
<p>La fusion se fait après le tri, et retient le premier élément<br class='autobr' />
rencontré. De cette manière, si un tableau est trie <code class='spip_code' dir='ltr'>{!par date}</code> puis fusionné sur l'email, l'enregistrement retenu pour chaque email sera le plus récent.</p> <p> </p> <p><i>Dans le prochain article, nous verrons <a href="http://www.spip.net/fr_article5443.html" class='spip_in'>des exemples de boucles <code class='spip_code' dir='ltr'>(DATA)</code></a>.</i></p></div>
		
		<img src="http://feeds.feedburner.com/~r/Spip/~4/eLwMJDLKL5M" height="1" width="1"/>]]></content:encoded>


		

	<feedburner:origLink>http://www.spip.net/fr_article5444.html</feedburner:origLink></item>



<media:rating>adult</media:rating></channel>

</rss>

