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

<channel>
	<title>wordpress Archives - Copier coller</title>
	<atom:link href="https://www.copier-coller.com/wordpress/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.copier-coller.com/wordpress/</link>
	<description>Des tutos wordpress pour les nuls !!!</description>
	<lastBuildDate>Sat, 19 Dec 2020 13:13:12 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.1.7</generator>

<image>
	<url>https://www.copier-coller.com/wp-content/uploads/2018/03/cropped-copier-coller_06_favicon-32x32.png</url>
	<title>wordpress Archives - Copier coller</title>
	<link>https://www.copier-coller.com/wordpress/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>ACF repeater field avec la version gratuite d&#8217;ACF</title>
		<link>https://www.copier-coller.com/acf-repeater-field-avec-la-version-gratuite-dacf/</link>
					<comments>https://www.copier-coller.com/acf-repeater-field-avec-la-version-gratuite-dacf/#respond</comments>
		
		<dc:creator><![CDATA[copier coller]]></dc:creator>
		<pubDate>Sat, 19 Dec 2020 13:13:12 +0000</pubDate>
				<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://www.copier-coller.com/?p=6203</guid>

					<description><![CDATA[<p>Les repeater-fields d&#8217;ACF permettent de créer des sous-champ aux traditionnels « custom fields » du plugin, donnant plus de flexibilité et de plus grandes possibilités d&#8217;affichage sur votre site. La bonne nouvelle, peu diffusée, c&#8217;est qu&#8217;Elliot Condom (l&#8217;auteur du plugin) lui même met à disposition sur une page GitHub une version isolée du « repeater field », et celle-ci [...]</p>
<p>The post <a rel="nofollow" href="https://www.copier-coller.com/acf-repeater-field-avec-la-version-gratuite-dacf/">ACF repeater field avec la version gratuite d&rsquo;ACF</a> appeared first on <a rel="nofollow" href="https://www.copier-coller.com">Copier coller</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Comment incorporer et utiliser les repeater field avec ACF ?</h2>
<p>Les repeater-fields d&rsquo;ACF permettent de créer des sous-champ aux traditionnels « custom fields » du plugin, donnant plus de flexibilité et de plus grandes possibilités d&rsquo;affichage sur votre site. La bonne nouvelle, peu diffusée, c&rsquo;est qu&rsquo;Elliot Condom (l&rsquo;auteur du plugin) lui même met à disposition sur une <a href="https://github.com/wab/acf-repeater">page GitHub</a> une version isolée du « repeater field », et celle-ci s&rsquo;incorpore parfaitement avec la version gratuite d&rsquo;ACF.</p>
<p>Sur un récent site, j&rsquo;ai pu tester et voir que ca marchait parfaitement. Cet add-on n&rsquo;a pas de page de configuration , il se retrouve automatiquement dans la liste de le menu déroulant des « types de champs » lors de la création d&rsquo;un « custom field. »</p>
<p>Ici je vais donc donner un exemple d&rsquo;utilisation pour montrer comment on peut s&rsquo;en servir.</p>
<h3>La création du champ principal et des sous-champ ACF</h3>
<p>Dans mon site de test, j&rsquo;ai un widget qui affiche des formations à venir, avec une mention de la ville et des dates associées. Chaque ville peut contenir plusieurs dates. C&rsquo;est là que l&rsquo;add-on « repeater » devient intéressant. L&rsquo;idée est donc de créer par ville, plusieurs sous champ pour toutes les dates de formation. L&rsquo;add-on permet en fait à l&rsquo;utilisateur qui édite la page de multiplier autant de dates que souhaité.</p>
<p>Mon champ principal, je l&rsquo;appelle donc « Réservations ».</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6204" src="https://www.copier-coller.com/wp-content/uploads/2020/12/repeater-field.png" alt="champ répéteur ACF gratuit" width="1403" height="840" srcset="https://www.copier-coller.com/wp-content/uploads/2020/12/repeater-field.png 1403w, https://www.copier-coller.com/wp-content/uploads/2020/12/repeater-field-300x180.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/12/repeater-field-1024x613.png 1024w, https://www.copier-coller.com/wp-content/uploads/2020/12/repeater-field-768x460.png 768w, https://www.copier-coller.com/wp-content/uploads/2020/12/repeater-field-624x374.png 624w" sizes="(max-width: 1403px) 100vw, 1403px" /></p>
<p>Dans « type de champ », et dans la section « disposition », je sélectionne le champ « répéteur ».</p>
<p>Cela va dérouler juste en dessous une nouvelle section « sous-champs ».</p>
<h3>Le sous champ « ville »</h3>
<p>A l&rsquo;intérieur je crée donc mes deux sous-champs « ville » et « dates ». Ville est un champ « select » ou « menu déroulant » dans lequel je place quelques villes. L&rsquo;utilisateur aura dans sa page d&rsquo;édition le choix entre ces villes prédéfinies.</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6206" src="https://www.copier-coller.com/wp-content/uploads/2020/12/ville-acf.png" alt="champ répéteur ACF gratuit" width="1154" height="790" srcset="https://www.copier-coller.com/wp-content/uploads/2020/12/ville-acf.png 1154w, https://www.copier-coller.com/wp-content/uploads/2020/12/ville-acf-300x205.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/12/ville-acf-1024x701.png 1024w, https://www.copier-coller.com/wp-content/uploads/2020/12/ville-acf-768x526.png 768w, https://www.copier-coller.com/wp-content/uploads/2020/12/ville-acf-624x427.png 624w" sizes="(max-width: 1154px) 100vw, 1154px" /></p>
<h3>Le sous champ « répéteur » date</h3>
<p>Pour les dates, je choisis à nouveau un champ « répéteur » dans lequel je place deux sous champ « date de début » et « date de fin ». L&rsquo;utilisateur pourra à l&rsquo;infini ajouter des dates pour chaque ville choisie.</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6205" src="https://www.copier-coller.com/wp-content/uploads/2020/12/dates-acf.png" alt="champ répéteur ACF gratuit" width="1235" height="756" srcset="https://www.copier-coller.com/wp-content/uploads/2020/12/dates-acf.png 1235w, https://www.copier-coller.com/wp-content/uploads/2020/12/dates-acf-300x184.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/12/dates-acf-1024x627.png 1024w, https://www.copier-coller.com/wp-content/uploads/2020/12/dates-acf-768x470.png 768w, https://www.copier-coller.com/wp-content/uploads/2020/12/dates-acf-624x382.png 624w" sizes="(max-width: 1235px) 100vw, 1235px" /></p>
<h3>Page d&rsquo;édition</h3>
<p>Dans la page d&rsquo;édition, l&rsquo;utilisateur retrouvera son champ additionnel « réservations », avec à l&rsquo;intérieur les sous-champ ville et date. Pour chaque ville sélectionnée, il pourra rajouter autant de dates que souhaité</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6207" src="https://www.copier-coller.com/wp-content/uploads/2020/12/acf-page-edition.png" alt="champ répéteur ACF gratuit" width="1577" height="751" srcset="https://www.copier-coller.com/wp-content/uploads/2020/12/acf-page-edition.png 1577w, https://www.copier-coller.com/wp-content/uploads/2020/12/acf-page-edition-300x143.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/12/acf-page-edition-1024x488.png 1024w, https://www.copier-coller.com/wp-content/uploads/2020/12/acf-page-edition-768x366.png 768w, https://www.copier-coller.com/wp-content/uploads/2020/12/acf-page-edition-1536x731.png 1536w, https://www.copier-coller.com/wp-content/uploads/2020/12/acf-page-edition-624x297.png 624w" sizes="(max-width: 1577px) 100vw, 1577px" /></p>
<h3>Afficher ses custom fields en front</h3>
<p>On peut ensuite se reporter à la<a href="https://www.advancedcustomfields.com/resources/repeater/"> doc officielle d&rsquo;ACF</a> pour comprendre comment afficher ses données sur le site. Ici on n&rsquo;appelle plus les champs individuellement avec des <em>get_field()</em> ou <em>the_field()</em>, mais on crée une boucle spécifique pour le champ répéteur et on utilise un <em>get_sub_field()</em> pour aller chercher les données des sous-champs, comme ci-dessous :</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;?php<br/><br/>// Check rows exists.<br/>if( have_rows(&#039;repeater_field_name&#039;) ):<br/><br/>    // Loop through rows.<br/>    while( have_rows(&#039;repeater_field_name&#039;) ) : the_row();<br/><br/>        // Load sub field value.<br/>        $sub_value = get_sub_field(&#039;sub_field&#039;);<br/>        // Do something...<br/><br/>    // End loop.<br/>    endwhile;<br/><br/>// No value.<br/>else :<br/>    // Do something...<br/>endif;</code></pre> <div class="code-embed-infos"> </div> </div>
<h3>créer un widget pour afficher ses villes et dates</h3>
<p>Pour cet exemple, je dois afficher ces données dans un widget. L&rsquo;utilisateur affiche en front et dans chaque page, article ou custom post type un widget contenant des villes et dates associées, pour chaque nouvelle formation à venir</p>
<p>Voici le code simplifié de mon widget:</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;?php<br/>class Monsite_Upcoming_Events extends WP_Widget {<br/>	function __construct() {<br/>	parent::__construct(<br/>		&#039;monsite_upcoming_events&#039;, // Base ID<br/>		__( &#039;Monsite Upcoming Events (Sidebar only)&#039;, &#039;text-domain&#039; ), // Name<br/>		array( &#039;description&#039; =&gt; __( &#039;Shows Formations dates&#039;, &#039;text-domain&#039; ), ) // Args<br/>	);<br/>} <br/>	public function form( $instance ) {<br/>		$title = &#039;&#039;;<br/>	    if( !empty( $instance[&#039;title&#039;] ) ) {<br/>	        $title = $instance[&#039;title&#039;];<br/>	    }<br/>	    ?&gt; <br/>		&lt;p&gt;<br/>		    &lt;label for=&quot;&lt;?php echo $this-&gt;get_field_id( &#039;title&#039; ); ?&gt;&quot;&gt;&lt;?php _e( &#039;Title&#039;, &#039;text-domain&#039; ); ?&gt;&lt;/label&gt;<br/>		    &lt;input type=&quot;text&quot; id=&quot;&lt;?php echo $this-&gt;get_field_id( &#039;title&#039; ); ?&gt;&quot; name=&quot;&lt;?php echo $this-&gt;get_field_name( &#039;title&#039; ); ?&gt;&quot; class=&quot;widefat&quot; value=&quot;&lt;?php echo esc_attr( $instance[&#039;title&#039;] ); ?&gt;&quot;&gt;<br/>		&lt;/p&gt;<br/>	&lt;?php<br/>	}<br/>	public function update( $new_instance, $old_instance ) {<br/>	    $instance = $old_instance;<br/>	    $instance[&#039;title&#039;] = $new_instance[&#039;title&#039;];<br/>	    return $instance;<br/>	}<br/>	public function widget( $args, $instance ) {<br/>		<br/>		<br/>		// vars<br/>		$title = get_the_title();		<br/>		if(have_rows(&#039;reservation&#039;)):<br/>			echo $args[&#039;before_widget&#039;];<br/>			if ( ! empty( $instance[&#039;title&#039;] ) ) {<br/>			echo $args[&#039;before_title&#039;] . apply_filters( &#039;widget_title&#039;, $instance[&#039;title&#039;] ). $args[&#039;after_title&#039;];<br/>		}<br/>		   while(have_rows(&#039;reservation&#039;)): the_row(); <br/>			$ville = get_sub_field(&#039;ville&#039;);<br/>			foreach($ville as $city){<br/> 			echo &#039;&lt;div class=&quot;event_entries&quot;&gt;&#039;;<br/>		            // Display city name.<br/>				echo &#039;&lt;h3&gt;&#039; .  $city . &#039;&lt;/h3&gt;&#039;;<br/>		           } <br/>				if(have_rows(&#039;dates&#039;)):<br/>				echo &#039;&lt;ul&gt;&#039;;<br/>				while(have_rows(&#039;dates&#039;)): the_row(); <br/>					$event_start_date = get_sub_field( &#039;date_de_debut&#039;  );<br/>					$event_end_date   = get_sub_field( &#039;date_de_fin&#039; );<br/>		            // Display posts in that city.<br/>		            <br/>		                if($event_start_date &amp;&amp;  $event_end_date){<br/>		                echo &#039;&lt;li&gt;&lt;a href=&quot;http://localhost/monsite/inscription/?titre=&#039;. $title . &#039;&amp;ville= à &#039;.  $city .&#039;&amp;date_de_debut=Session du &#039; .  $event_start_date .&#039;&amp;date_de_fin= au &#039; .  $event_end_date .&#039;&quot;&gt; Du &#039; . $event_start_date . &#039; au &#039; . $event_end_date . &#039;&lt;/a&gt;&lt;/li&gt;&#039;;				<br/>		            }<br/>		           <br/>	 			endwhile; <br/>				echo &#039;&lt;/ul&gt;&#039;;<br/>				endif;	<br/>			echo &#039;&lt;/div&gt;&#039;; <br/>			endwhile;<br/>			endif;<br/>		echo $args[&#039;after_widget&#039;];<br/>	}<br/>}</code></pre> <div class="code-embed-infos"> </div> </div>
<h3>Détail du widget</h3>
<p>Voici un rendu possible du widget crée. Le widget ne comporte aucune option, il sert juste à afficher les données insérées par l&rsquo;utilisateur. Dans la page des widget dans Apparence/widget, il suffit juste de placer le widget dans la page de son choix. En front il affiche les villes sélectionnées dans la page d&rsquo;édition, et toutes les dates correspondantes.</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6208" src="https://www.copier-coller.com/wp-content/uploads/2020/12/rendu-acf-repeater.png" alt="rendu de widget avec ACF Repeater" width="373" height="402" srcset="https://www.copier-coller.com/wp-content/uploads/2020/12/rendu-acf-repeater.png 373w, https://www.copier-coller.com/wp-content/uploads/2020/12/rendu-acf-repeater-278x300.png 278w" sizes="(max-width: 373px) 100vw, 373px" /></p>
<p>Dans la fonction widget, on construit donc l&rsquo;apparence de ce dernier : on commence donc par la boucle citée plus haut :</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">if(have_rows(&#039;reservation&#039;)): while(have_rows(&#039;reservation&#039;)): the_row(); </code></pre> <div class="code-embed-infos"> </div> </div>
<p>on récupère le sous-champ ville, et on affiche toutes les villes dans un titre :</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">$ville = get_sub_field(&#039;ville&#039;);<br/>			foreach($ville as $city){<br/> 			echo &#039;&lt;div class=&quot;event_entries&quot;&gt;&#039;;<br/>		            // Display city name.<br/>				echo &#039;&lt;h3&gt;&#039; .  $city . &#039;&lt;/h3&gt;&#039;;<br/>		           } </code></pre> <div class="code-embed-infos"> </div> </div>
<p>Puis à l&rsquo;intérieur du foreach, on recrée une seconde boucle, pour récupérer toutes les dates associées</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">if(have_rows(&#039;dates&#039;)):<br/>				echo &#039;&lt;ul&gt;&#039;;<br/>				while(have_rows(&#039;dates&#039;)): the_row(); <br/>					$event_start_date = get_sub_field( &#039;date_de_debut&#039;  );<br/>					$event_end_date   = get_sub_field( &#039;date_de_fin&#039; );<br/><br/>......</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Le reste est propre à cet exemple : je crée un url dynamique avec des querys tring : chaque ligne contenant une date de début et de fin constitue en fait un lien qui pointera vers un formulaire déjà prérempli.</p>
<p>Voilà, le but ici est surtout de montrer qu&rsquo;on n&rsquo;a pas forcément besoin de la version pro d&rsquo;ACF pour créer des sous champ « répéteur », et qu&rsquo;en l&rsquo;état, cette configuration permet déjà d&rsquo;aller beaucoup plus loin qu&rsquo;avec la version simple d&rsquo;ACF. Sans ca, on serait obligé de créer des boucles beaucoup plus complexes pour arriver au même résultat.</p>
<p>The post <a rel="nofollow" href="https://www.copier-coller.com/acf-repeater-field-avec-la-version-gratuite-dacf/">ACF repeater field avec la version gratuite d&rsquo;ACF</a> appeared first on <a rel="nofollow" href="https://www.copier-coller.com">Copier coller</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.copier-coller.com/acf-repeater-field-avec-la-version-gratuite-dacf/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Comment consolider le comportement du menu pour vos CPT</title>
		<link>https://www.copier-coller.com/comment-consolider-le-comportement-du-menu-pour-vos-cpt/</link>
					<comments>https://www.copier-coller.com/comment-consolider-le-comportement-du-menu-pour-vos-cpt/#respond</comments>
		
		<dc:creator><![CDATA[copier coller]]></dc:creator>
		<pubDate>Sun, 26 Apr 2020 18:00:12 +0000</pubDate>
				<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://www.copier-coller.com/?p=6093</guid>

					<description><![CDATA[<p>Cet article fait suite au précédent, dans lequel je donne un exemple de contournement pour créer une page d&#8217;archive de custom post type personnalisée. Lorsque vous créez un custom post type, WordPress en effet va générer automatiquement une page d&#8217;archive que vous pourrez retrouver dans l&#8217;onglet Apparence / menu. C&#8217;est une page qui n&#8217;existe pas [...]</p>
<p>The post <a rel="nofollow" href="https://www.copier-coller.com/comment-consolider-le-comportement-du-menu-pour-vos-cpt/">Comment consolider le comportement du menu pour vos CPT</a> appeared first on <a rel="nofollow" href="https://www.copier-coller.com">Copier coller</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Comment consolider le comportement du menu pour vos CPT ?</h2>
<p>Cet article fait suite <a href="https://www.copier-coller.com/creer-des-pages-darchive-pour-vos-custom-post-type/">au précédent</a>, dans lequel je donne un exemple de contournement pour créer une page d&rsquo;archive de custom post type personnalisée. Lorsque vous créez un custom post type, WordPress en effet va générer automatiquement une page d&rsquo;archive que vous pourrez retrouver dans l&rsquo;onglet Apparence / menu. C&rsquo;est une page qui n&rsquo;existe pas en dur dans le dossier wordpress, et qu&rsquo;on ne peut malheureusement pas personnaliser.</p>
<p>On a donc vu comment contourner cette contrainte, en créant un modèle de page qui prend le rôle de page d&rsquo;archive.</p>
<h3>Le problème</h3>
<p>Le problème, c&rsquo;est qu&rsquo;il reste à modifier le comportement du menu wordpress qui se perd un peu dans l&rsquo;arborescence. Il se peut que wordpress souligne la page blog lorsque vous êtes dans un article de custom post type, comme si la page blog était parente de vos CPT.</p>
<p>Pour contourner ce dysfonctionnement, et si vous avez placé votre page d&rsquo;archive personnalisée dans le menu, voici le code à insérer dans functions.php</p>
<h3>La solution</h3>
<p>Ce code vous permettra, lorsque vous êtes dans une page single CPT, de surligner le modèle de page plutôt que la page blog, comme s&rsquo;il s&rsquo;agissait d&rsquo;une page d&rsquo;archive parente classique.</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code"><br/>/* PREVENT BLOG CURENT MENU ITEM CLASS ON CPT*/<br/>add_filter( &#039;nav_menu_css_class&#039;, &#039;theme_remove_cpt_blog_class&#039;, 10, 3 );<br/>function theme_remove_cpt_blog_class( $classes, $item, $args ) {<br/>    if( !is_singular( &#039;post&#039; ) AND !is_category() AND !is_tag() AND !is_date() ):<br/>        $blog_page_id = intval( get_option( &#039;page_for_posts&#039; ) );<br/>        if( $blog_page_id != 0 AND $item-&gt;object_id == $blog_page_id )<br/>            unset( $classes[ array_search( &#039;current_page_parent&#039;, $classes ) ] ); <br/>    endif;<br/>    return $classes;<br/>}<br/><br/>/* ADD CURRENT MENU ITEM CLASS ON CPT PARENT PAGE */<br/>add_action( &#039;nav_menu_css_class&#039;, &#039;theme_add_cpt_ancestor_class&#039;, 10, 3 );<br/>function theme_add_cpt_ancestor_class( $classes, $item, $args ) {<br/>    global $post;<br/>    $current_post_type = get_post_type_object( get_post_type( $post-&gt;ID ) );<br/>    $current_post_type_slug = $current_post_type-&gt;rewrite[ &#039;slug&#039; ];<br/>    $menu_slug = strtolower( trim( $item-&gt;url ) );<br/>    if( strpos( $menu_slug, $current_post_type_slug ) !== false )<br/>        $classes[] = &#039;current_page_parent&#039;;<br/>    return $classes;<br/>}</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Cette action et ce filtre permettent de retirer la classe <em>current_page_parent</em> que wordpress attribue automatiquement à la page blog, et de la réattribuer à votre modèle de page.</p>
<p>L&rsquo;utilisateur ne verra donc plus aucune différence entre le modèle de page et une vraie page d&rsquo;archive.</p>
<p>The post <a rel="nofollow" href="https://www.copier-coller.com/comment-consolider-le-comportement-du-menu-pour-vos-cpt/">Comment consolider le comportement du menu pour vos CPT</a> appeared first on <a rel="nofollow" href="https://www.copier-coller.com">Copier coller</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.copier-coller.com/comment-consolider-le-comportement-du-menu-pour-vos-cpt/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Créer des pages d&#8217;archive pour vos custom post type</title>
		<link>https://www.copier-coller.com/creer-des-pages-darchive-pour-vos-custom-post-type/</link>
					<comments>https://www.copier-coller.com/creer-des-pages-darchive-pour-vos-custom-post-type/#comments</comments>
		
		<dc:creator><![CDATA[copier coller]]></dc:creator>
		<pubDate>Sat, 25 Apr 2020 18:00:56 +0000</pubDate>
				<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://www.copier-coller.com/?p=6090</guid>

					<description><![CDATA[<p>Dans cet article, nous allons voir comment outrepasser le fonctionnement par défaut de wordpress concernant les custom post type. Normalement, à la création de votre custom post type, si l&#8217;on donne comme argument « has_archive » =&#62;&#8217;true&#8216; à notre CPT, wordpress va automatiquement créer une page d&#8217;archive qui affichera tous nos custom post type. Le problème c&#8217;est [...]</p>
<p>The post <a rel="nofollow" href="https://www.copier-coller.com/creer-des-pages-darchive-pour-vos-custom-post-type/">Créer des pages d&rsquo;archive pour vos custom post type</a> appeared first on <a rel="nofollow" href="https://www.copier-coller.com">Copier coller</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Comment créer des pages d&rsquo;archives customisées pour vos custom post type ?</h2>
<p>Dans cet article, nous allons voir comment outrepasser le fonctionnement par défaut de wordpress concernant les custom post type. Normalement, à la création de votre <em>custom post type</em>, si l&rsquo;on donne comme argument « <em>has_archive » =&gt;&rsquo;true</em>&lsquo; à notre CPT, wordpress va automatiquement créer une page d&rsquo;archive qui affichera tous nos custom post type.</p>
<h3>Le problème</h3>
<p>Le problème c&rsquo;est que cette page n&rsquo;est pas générée dans le dossier wordpress, on ne peut donc pas la modifier par le code. Dans le cas de l&rsquo;utilisation d&rsquo;un page builder, Elementor ou autre, vous ne pourrez pas éditer la page.</p>
<h3>La solution</h3>
<p>Si vous utilisez un page builder et que vous avez besoin de modifier la page ou la rendre administrable pour l&rsquo;utilisateur final, il faut donc impérativement trouver une solution. Celle-ci consiste en fait à créer un modèle de page d&rsquo;archive pour notre custom post type.</p>
<h3>La création du custom post type</h3>
<p style="line-height: 1.71429; margin-bottom: 1.71429rem;">Voici le code de création d&rsquo;un custom post type. Ici, notre custom post type s&rsquo;appelle « formation »</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">function cc_formation_cpt() {<br/>	/* Formation */<br/>	$labels = array(<br/>		&#039;name&#039;                =&gt; _x(&#039;Formations&#039;, &#039;Post Type General Name&#039;, &#039;text_domain&#039;),<br/>		&#039;singular_name&#039;       =&gt; _x(&#039;Formation&#039;, &#039;Post Type Singular Name&#039;, &#039;text_domain&#039;),<br/>		&#039;menu_name&#039;           =&gt; _x(&#039;Formations&#039;, &#039;text_domain&#039;),<br/>		&#039;name_admin_bar&#039;      =&gt; _x(&#039;Formations&#039;, &#039;text_domain&#039;),<br/>		&#039;all_items&#039;           =&gt; _x(&#039;Toutes les formations&#039;, &#039;text_domain&#039;),<br/>		&#039;add_new_item&#039;        =&gt; _x(&#039;Ajouter une nouvelle formation&#039;, &#039;text_domain&#039;),<br/>		&#039;add_new&#039;             =&gt; _x(&#039;Ajouter&#039;, &#039;text_domain&#039;),<br/>		&#039;new_item&#039;            =&gt; _x(&#039;Nouvelle formation&#039;, &#039;text_domain&#039; ),<br/>		&#039;edit_item&#039;           =&gt; _x(&#039;Editer la formation&#039;, &#039;text_domain&#039;),<br/>		&#039;update_item&#039;         =&gt; _x(&#039;Mettre à jour la formation&#039;, &#039;text_domain&#039;),<br/>		&#039;view_item&#039;           =&gt; _x(&#039;Voir la formation&#039;, &#039;text_domain&#039;),<br/>		&#039;search_items&#039;        =&gt; _x(&#039;Rechercher une formation&#039;, &#039;text_domain&#039;),<br/>		&#039;not_found&#039;           =&gt; _x(&#039;Aucune formation trouvée&#039;, &#039;text_domain&#039;),<br/>		&#039;not_found_in_trash&#039;  =&gt; _x(&#039;Aucune formation trouvée dans la corbeille&#039;, &#039;text_domain&#039;),<br/>	);<br/>	<br/>	$args = array(<br/>		&#039;label&#039;               =&gt; _x(&#039;Formation&#039;, &#039;text_domain&#039;),<br/>		&#039;description&#039;         =&gt; _x(&#039;Formations&#039;, &#039;text_domain&#039;),<br/>		&#039;labels&#039;              =&gt; $labels,<br/>		&#039;supports&#039;            =&gt; array(&#039;title&#039;, &#039;editor&#039;, &#039;thumbnail&#039;, &#039;comments&#039;, &#039;revisions&#039;, &#039;custom-fields&#039;),<br/>		&#039;hierarchical&#039;        =&gt; false,<br/>		&#039;public&#039;              =&gt; true,<br/>		&#039;show_ui&#039;             =&gt; true,<br/>		&#039;show_in_menu&#039;        =&gt; true,<br/>		&#039;menu_position&#039;       =&gt; 5,<br/>		&#039;menu_icon&#039;           =&gt; &#039;dashicons-admin-home&#039;,<br/>		&#039;show_in_admin_bar&#039;   =&gt; true,<br/>		&#039;show_in_nav_menus&#039;   =&gt; true,<br/>		&#039;can_export&#039;          =&gt; true,<br/>		&#039;has_archive&#039;         =&gt; false,<br/>		&#039;exclude_from_search&#039; =&gt; false,<br/>		&#039;publicly_queryable&#039;  =&gt; true,<br/>		&#039;query_var&#039;           =&gt; true,<br/>		&#039;rewrite&#039;             =&gt;  array( &#039;slug&#039; =&gt; &#039;toutes-nos-formations&#039; ),<br/>		&#039;capability_type&#039;     =&gt; &#039;post&#039;,<br/>		&#039;show_in_rest&#039;			=&gt;&#039;true&#039;,<br/>	);<br/>	register_post_type(&#039;formation&#039;, $args);	<br/>}<br/>add_action(&#039;init&#039;, &#039;cc_formation_cpt&#039;, 10);</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Si on laisse ici « <em>has_archive » = »true</em> » , on peut retrouver un onglet qui s&rsquo;appelerait « toutes les formations » dans l&rsquo;onglet Apparence / Menu du backoffice. On aurait donc automatiquement une page avec tous les articles lis à ce custom post type.</p>
<p>Nous on passe ce paramètre « <em>has_archive</em> » à false, et on crée par la même occasion une réécriture d&rsquo;url :</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&#039;rewrite&#039; =&gt; array( &#039;slug&#039; =&gt; &#039;toutes-nos-formations&#039; ),</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Cela garantit que WP ne crée pas d&rsquo;archive réelle et accepte notre modèle de page à la place. La réécriture garantit notamment que les CPT individuels seront publiés de manière à ressembler à des « enfants » de cette page, même s&rsquo;ils ne le sont pas en réalité !</p>
<h3>La création du modèle de page</h3>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">Template Name: Toutes nos Formations</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Tout en haut de notre nouveau fichier php, on signifie à worpdress qu&rsquo;on est là sur un nouveau modèle de page « Toutes nos formations ». Le nom doit être le même que celui indiqué dans la réécriture d&rsquo;url. Dans le backoffice de wordpress, on crée ensuite notre nouvelle page « Toutes nos formations » et on lui attribue comme modèle de page « Toutes nos formations ».</p>
<h3>Une page administrable</h3>
<p>Dans cette page, on va donc pouvoir coder en dur tout ce qu&rsquo;on veut, cela occupera un espace dans la page en front. On va notamment créer la boucle qui va ramener tous nos custom post type. Il s&rsquo;agit ici de simuler le comportement d&rsquo;une page d&rsquo;archive classique .</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;?php <br/>			$paged = (get_query_var(&#039;paged&#039;)) ? get_query_var(&#039;paged&#039;) : 1;<br/>			$args=array(<br/>			&#039;post_type&#039; =&gt;&#039;formation&#039;,<br/>			&#039;posts_per_page&#039; =&gt;5,<br/>			&#039;paged&#039; =&gt; $paged<br/><br/>			);<br/>			$query = new WP_Query( $args ); //Check the WP_Query docs to see how you can limit which posts to display ?&gt;<br/>			&lt;?php if ( $query-&gt;have_posts() ) : ?&gt;</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Pour le reste, on peut appeler le template_tag <strong><em>the_content()</em></strong> normalement, afin que l&rsquo;utilisateur puisse administrer le reste de la page via l&rsquo;éditeur de wordpress, Elementor, ou tout autre page builder</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;?php		<br/>		if ( have_posts() ) :<br/>			while ( have_posts() ) : the_post();<br/>			the_content();<br/>			endwhile; <br/>			endif;		<br/>		;?&gt;</code></pre> <div class="code-embed-infos"> </div> </div>
<h3>Le breadcrumb</h3>
<p>Sans modification supplémentaire, le fil d’Ariane va continuer à afficher le nom de la page d&rsquo;archive générée automatiquement par wordpress. Il va donc falloir le modifier. Si on utilise Yoast SEO, voici un bout de code qui permet de modifier ce fil d’Ariane.</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;?php<br/>function cc_filter_yoast_breadcrumbs( $links ) {<br/>    // Only affect individual &quot;mycpt&quot; CPTs<br/>    if ( is_singular( &#039;mycpt&#039; ) ) {<br/>        // Add &quot;My CPT&quot; breadcrumb<br/>        $addedBreadcrumbs = array(<br/>            array( &#039;text&#039; =&gt; &#039;My CPT&#039;, &#039;url&#039; =&gt; &#039;/mycpt/&#039;, &#039;allow_html&#039; =&gt; 1)<br/>        );<br/>        // Add the new breadcrumb before the single CPT title<br/>        array_splice( $links, 1, 0, $addedBreadcrumbs );<br/>    }<br/>    // Always return the links, even if we didn&#039;t change them<br/>    return $links;<br/>}<br/>add_filter( &#039;wpseo_breadcrumb_links&#039;, &#039;cc_filter_yoast_breadcrumbs&#039; );<br/>?&gt;</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Adapté à notre exemple, voici ce que cela donne:</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">function cc_formation_filter_yoast_breadcrumbs( $links ) {<br/>   <br/>    if ( is_singular( &#039;formation&#039; ) ) {<br/>       <br/>        $addedBreadcrumbs = array(<br/>            array( &#039;text&#039; =&gt; &#039;Toutes nos formations&#039;, &#039;url&#039; =&gt; &#039;/mon site/toutes-nos-formations/&#039;, &#039;allow_html&#039; =&gt; 1)<br/>        );<br/>        <br/>        array_splice( $links, 1, 0, $addedBreadcrumbs );<br/>    }<br/>    <br/>    return $links;<br/>}<br/>add_filter( &#039;wpseo_breadcrumb_links&#039;, &#039;cc_formation_filter_yoast_breadcrumbs&#039; );</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Maintenant, lorsque vous serez dans votre article du custom post type, le fil d’Ariane affichera le nom de votre modèle de page crée précédemment. L&rsquo;utilisateur ne pourra donc plus tomber sur la page d&rsquo;archive générée par wordpress.</p>
<h4>Sources :</h4>
<p>Cette astuce m&rsquo;a été donnée par <a href="https://wordpress.stackexchange.com/users/102815/webelaine">WebElaine</a> sur stackoveflow.</p>
<p>The post <a rel="nofollow" href="https://www.copier-coller.com/creer-des-pages-darchive-pour-vos-custom-post-type/">Créer des pages d&rsquo;archive pour vos custom post type</a> appeared first on <a rel="nofollow" href="https://www.copier-coller.com">Copier coller</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.copier-coller.com/creer-des-pages-darchive-pour-vos-custom-post-type/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Système de filtres avancés pour custom post type</title>
		<link>https://www.copier-coller.com/systeme-de-filtres-avances-pour-custom-post-type/</link>
					<comments>https://www.copier-coller.com/systeme-de-filtres-avances-pour-custom-post-type/#respond</comments>
		
		<dc:creator><![CDATA[copier coller]]></dc:creator>
		<pubDate>Tue, 21 Apr 2020 18:07:31 +0000</pubDate>
				<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://www.copier-coller.com/?p=6107</guid>

					<description><![CDATA[<p>Cet article fait suite aux deux précédents articles sur les systèmes de filtres et bouton ajax load more dans les articles et les custom post type. Ici, je poste un autre exemple avec un système de filtre un peu plus avancé, avec deux taxonomies :  la catégorie et le niveau. Mon arborescence et la structure [...]</p>
<p>The post <a rel="nofollow" href="https://www.copier-coller.com/systeme-de-filtres-avances-pour-custom-post-type/">Système de filtres avancés pour custom post type</a> appeared first on <a rel="nofollow" href="https://www.copier-coller.com">Copier coller</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Comment créer un système de filtre avancés pour vos custom post type ?</h2>
<p>Cet article fait suite aux deux précédents articles sur les systèmes de filtres et bouton <em>ajax load more</em> dans les <a href="https://www.copier-coller.com/?p=6075">articles</a> et les <a href="https://www.copier-coller.com/?p=6100">custom post type</a>.</p>
<h3>Mon système de filtre avancé</h3>
<p>Ici, je poste un autre exemple avec un système de filtre un peu plus avancé, avec deux taxonomies :  la catégorie et le niveau. Mon arborescence et la structure des fichiers est la même que pour les deux derniers articles cités. Je ne poste donc ici que la partie de code utile.</p>
<p>Voici le rendu souhaité de mes filtres : deux rangées, une pour chaque taxonomie. Chaque rangée possède un bouton de réinitialisation, pour que l&rsquo;utilisateur puisse annuler le filtre d&rsquo;une rangée tout en gardant un autre filtre activé.</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6108" src="https://www.copier-coller.com/wp-content/uploads/2020/04/filtres.png" alt="" width="843" height="214" srcset="https://www.copier-coller.com/wp-content/uploads/2020/04/filtres.png 843w, https://www.copier-coller.com/wp-content/uploads/2020/04/filtres-300x76.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/04/filtres-768x195.png 768w, https://www.copier-coller.com/wp-content/uploads/2020/04/filtres-624x158.png 624w" sizes="(max-width: 843px) 100vw, 843px" /></p>
<h3>Mon custom post type</h3>
<p>Je commence donc par créer mon custom post type, ainsi que les taxonomies associées.</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">/*AVIS*/<br/>function cc_cpt_review() {<br/>	/* Formation */<br/>	$labels = array(<br/>		&#039;name&#039;                =&gt; _x(&#039;Avis&#039;, &#039;Post Type General Name&#039;, &#039;text_domain&#039;),<br/>		&#039;singular_name&#039;       =&gt; _x(&#039;Avis&#039;, &#039;Post Type Singular Name&#039;, &#039;text_domain&#039;),<br/>		&#039;menu_name&#039;           =&gt; _x(&#039;Avis&#039;, &#039;text_domain&#039;),<br/>		&#039;name_admin_bar&#039;      =&gt; _x(&#039;Avis&#039;, &#039;text_domain&#039;),<br/>		&#039;all_items&#039;           =&gt; _x(&#039;Tous les Avis&#039;, &#039;text_domain&#039;),<br/>		&#039;add_new_item&#039;        =&gt; _x(&#039;Ajouter un nouvel Avis&#039;, &#039;text_domain&#039;),<br/>		&#039;add_new&#039;             =&gt; _x(&#039;Ajouter&#039;, &#039;text_domain&#039;),<br/>		&#039;new_item&#039;            =&gt; _x(&#039;Nouvel avis&#039;, &#039;text_domain&#039; ),<br/>		&#039;edit_item&#039;           =&gt; _x(&#039;Editer l\&#039;avis&#039;, &#039;text_domain&#039;),<br/>		&#039;update_item&#039;         =&gt; _x(&#039;Mettre à jour l\&#039;avis&#039;, &#039;text_domain&#039;),<br/>		&#039;view_item&#039;           =&gt; _x(&#039;Voir l\&#039;avis&#039;, &#039;text_domain&#039;),<br/>		&#039;search_items&#039;        =&gt; _x(&#039;Rechercher un avis&#039;, &#039;text_domain&#039;),<br/>		&#039;not_found&#039;           =&gt; _x(&#039;Aucun avis trouvé&#039;, &#039;text_domain&#039;),<br/>		&#039;not_found_in_trash&#039;  =&gt; _x(&#039;Aucun avis trouvé dans la corbeille&#039;, &#039;text_domain&#039;),<br/>	);<br/>	<br/>	$args = array(<br/>		&#039;label&#039;               =&gt; _x(&#039;Avis&#039;, &#039;text_domain&#039;),<br/>		&#039;description&#039;         =&gt; _x(&#039;Avis&#039;, &#039;text_domain&#039;),<br/>		&#039;labels&#039;              =&gt; $labels,<br/>		&#039;supports&#039;            =&gt; array(&#039;title&#039;, &#039;editor&#039;, &#039;thumbnail&#039;, &#039;comments&#039;, &#039;revisions&#039;, &#039;custom-fields&#039;),<br/>		&#039;hierarchical&#039;        =&gt; false,<br/>		&#039;public&#039;              =&gt; true,<br/>		&#039;show_ui&#039;             =&gt; true,<br/>		&#039;show_in_menu&#039;        =&gt; true,<br/>		&#039;menu_position&#039;       =&gt; 5,<br/>		&#039;menu_icon&#039;           =&gt; &#039;dashicons-admin-home&#039;,<br/>		&#039;show_in_admin_bar&#039;   =&gt; true,<br/>		&#039;show_in_nav_menus&#039;   =&gt; true,<br/>		&#039;can_export&#039;          =&gt; true,<br/>		&#039;has_archive&#039;         =&gt; false,<br/>		&#039;exclude_from_search&#039; =&gt; false,<br/>		&#039;publicly_queryable&#039;  =&gt; true,<br/>		&#039;query_var&#039;           =&gt; &#039;avis&#039;,<br/>		&#039;rewrite&#039;             =&gt;  array( &#039;slug&#039; =&gt; &#039;tous-les-avis&#039; ),<br/>		&#039;capability_type&#039;     =&gt; &#039;post&#039;,<br/>		&#039;show_in_rest&#039;			=&gt;&#039;true&#039;,<br/>	);<br/>	register_post_type(&#039;avis&#039;, $args);	<br/>}<br/>add_action(&#039;init&#039;, &#039;cc_cpt_review&#039;, 10);<br/><br/><br/><br/>function cc_add_taxonomies_review() {<br/>	// Catégorie de série<br/>	$labels_cat_avis = array(<br/>		&#039;name&#039;                       =&gt; _x( &#039;Catégories de l\&#039;avis&#039;, &#039;taxonomy general name&#039;),<br/>		&#039;singular_name&#039;              =&gt; _x( &#039;Catégories de l\&#039;avis&#039;, &#039;taxonomy singular name&#039;),<br/>		&#039;search_items&#039;               =&gt; __( &#039;Rechercher une catégorie&#039;),<br/>		&#039;popular_items&#039;              =&gt; __( &#039;Catégories populaires&#039;),<br/>		&#039;all_items&#039;                  =&gt; __( &#039;Toutes les catégories&#039;),<br/>		&#039;edit_item&#039;                  =&gt; __( &#039;Editer une catégorie&#039;),<br/>		&#039;update_item&#039;                =&gt; __( &#039;Mettre à jour une catégorie&#039;),<br/>		&#039;add_new_item&#039;               =&gt; __( &#039;Ajouter une nouvelle catégorie&#039;),<br/>		&#039;new_item_name&#039;              =&gt; __( &#039;Nom de la nouvelle catégorie&#039;),<br/>		&#039;add_or_remove_items&#039;        =&gt; __( &#039;Ajouter ou supprimer une catégorie&#039;),<br/>		&#039;choose_from_most_used&#039;      =&gt; __( &#039;Choisir parmi les catégories les plus utilisées&#039;),<br/>		&#039;not_found&#039;                  =&gt; __( &#039;Pas de catégories trouvée&#039;),<br/>		&#039;menu_name&#039;                  =&gt; __( &#039;Catégorie d\&#039;avis&#039;),<br/>	);<br/><br/>	$args_cat_avis = array(<br/><br/>		&#039;hierarchical&#039;          =&gt; true,<br/>		&#039;labels&#039;                =&gt; $labels_cat_avis,<br/>		&#039;show_ui&#039;               =&gt; true,<br/>		&#039;show_in_rest&#039;			=&gt; true,<br/>		&#039;show_admin_column&#039;     =&gt; true,<br/>		&#039;query_var&#039;             =&gt; true,<br/>		&#039;rewrite&#039;               =&gt; array( &#039;slug&#039; =&gt; &#039;categories-avis&#039; ),<br/>	);<br/><br/>	register_taxonomy( &#039;categories-avis&#039;, &#039;avis&#039;, $args_cat_avis );<br/>}<br/>add_action( &#039;init&#039;, &#039;cc_add_taxonomies_review&#039;, 0 );<br/><br/>function cc_avis_level_taxonomies() {<br/><br/>	$labels_level_avis = array(<br/>		&#039;name&#039;                       =&gt; _x( &#039;Niveaux de l\&#039;avis&#039;, &#039;taxonomy general name&#039;),<br/>		&#039;singular_name&#039;              =&gt; _x( &#039;Niveau de l\&#039;avis&#039;, &#039;taxonomy singular name&#039;),<br/>		&#039;search_items&#039;               =&gt; __( &#039;Rechercher un avis&#039;),<br/>		&#039;popular_items&#039;              =&gt; __( &#039;Niveaux populaires&#039;),<br/>		&#039;all_items&#039;                  =&gt; __( &#039;Tous les Niveaux&#039;),<br/>		&#039;edit_item&#039;                  =&gt; __( &#039;Editer un niveau&#039;),<br/>		&#039;update_item&#039;                =&gt; __( &#039;Mettre à jour un niveau&#039;),<br/>		&#039;add_new_item&#039;               =&gt; __( &#039;Ajouter un nouveau niveau&#039;),<br/>		&#039;new_item_name&#039;              =&gt; __( &#039;Nom de le nouveau niveau&#039;),<br/>		&#039;add_or_remove_items&#039;        =&gt; __( &#039;Ajouter ou supprimer un niveau&#039;),<br/>		&#039;choose_from_most_used&#039;      =&gt; __( &#039;Choisir parmi les niveaux les plus utilisés&#039;),<br/>		&#039;not_found&#039;                  =&gt; __( &#039;Pas de niveau trouvé&#039;),<br/>		&#039;menu_name&#039;                  =&gt; __( &#039;Niveau de l\&#039;avis&#039;),<br/>	);<br/><br/>	$args_level_avis = array(<br/>	<br/>		&#039;hierarchical&#039;          =&gt; true,<br/>		&#039;labels&#039;                =&gt; $labels_level_avis,<br/>		&#039;show_ui&#039;               =&gt; true,<br/>		&#039;show_in_rest&#039;			=&gt; true,<br/>		&#039;show_admin_column&#039;     =&gt; true,<br/>		&#039;query_var&#039;             =&gt; true,<br/>		&#039;rewrite&#039;               =&gt; array( &#039;slug&#039; =&gt; &#039;niveau-avis&#039; ),<br/>	);<br/><br/>	register_taxonomy( &#039;niveau-avis&#039;, &#039;avis&#039;, $args_level_avis );<br/>}<br/>add_action( &#039;init&#039;, &#039;cc_avis_level_taxonomies&#039;, 0 );</code></pre> <div class="code-embed-infos"> </div> </div>
<h3>Mon modèle de page ou page d&rsquo;archive</h3>
<p>Dans ma page d&rsquo;archive personnalisée ou modèle de page, je crée deux formulaires de filtrage, un pour chacune de mes taxonomies.</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;div class=&quot;flex-row&quot;&gt;<br/>				&lt;form action=&quot;#&quot; method=&quot;POST&quot; id=&quot;avis_filters&quot; class=&quot;flex-row&quot;&gt;<br/>					&lt;div class=&quot;flex-row&quot;&gt;<br/>					&lt;input type=&quot;radio&quot; value=&quot;all_categ&quot; id=&quot;all_categ&quot; class=&quot;avis_filter&quot; name=&quot;category_avis_filters&quot;&gt;&lt;label for=&quot;all_categ&quot;&gt;Toutes&lt;/label&gt;<br/>					<br/>					&lt;?php <br/>					if( $terms = get_terms( array( &#039;taxonomy&#039; =&gt; &#039;categories-avis&#039; ) ) ) :<br/>						foreach( $terms as $term ) :<br/>							echo &#039;&lt;input type=&quot;radio&quot; id=&quot;&#039; . $term-&gt;term_id . &#039;&quot; value=&quot;&#039; . $term-&gt;term_id . &#039;&quot; name=&quot;category_avis_filters&quot; class=&quot;avis_filters&quot;/&gt;&lt;label for=&quot;&#039; . $term-&gt;term_id. &#039;&quot;&gt;&#039; . $term-&gt;name . &#039;&lt;/label&gt;&#039;;<br/>						endforeach;<br/>					endif;<br/>					?&gt;<br/>				&lt;/div&gt;<br/>				&lt;div class=&quot;flex-row&quot;&gt;<br/>					&lt;input type=&quot;radio&quot; value=&quot;all_niveau&quot; id=&quot;all_niveau&quot; class=&quot;avis_filter&quot; name=&quot;niveau_avis_filters&quot;&gt;&lt;label for=&quot;all_niveau&quot;&gt;Toutes&lt;/label&gt;<br/>					<br/>					&lt;?php <br/>						if( $terms = get_terms( array( &#039;taxonomy&#039; =&gt; &#039;niveau-avis&#039; ) ) ) :<br/>							foreach( $terms as $term ) :<br/>								echo &#039;&lt;input type=&quot;radio&quot; id=&quot;&#039; . $term-&gt;term_id . &#039;&quot; value=&quot;&#039; . $term-&gt;term_id . &#039;&quot; name=&quot;niveau_avis_filters&quot; class=&quot;avis_filters&quot;/&gt;&lt;label for=&quot;&#039; . $term-&gt;term_id. &#039;&quot;&gt;&#039; . $term-&gt;name . &#039;&lt;/label&gt;&#039;;<br/>							endforeach;<br/>						endif;?&gt;<br/>					&lt;/div&gt;<br/>					&lt;!-- required hidden field for admin-ajax.php --&gt;<br/>					&lt;input type=&quot;hidden&quot; name=&quot;action&quot; value=&quot;ccavisfilter&quot; /&gt;<br/>				&lt;/form&gt;<br/>			&lt;/div&gt;<br/>		<br/>		   &lt;?php <br/>			// le début de ma boucle<br/>			$paged = (get_query_var(&#039;paged&#039;)) ? get_query_var(&#039;paged&#039;) : 1;<br/>			$args = array(<br/>				&#039;post_type&#039; =&gt;&#039;avis&#039;,<br/>				&#039;posts_per_page&#039; =&gt;5,<br/>				&#039;paged&#039; =&gt; $paged<br/>			);<br/>			$query = new WP_Query( $args ); ?&gt;<br/>			&lt;?php if ( $query-&gt;have_posts() ) : ?&gt;<br/>		    &lt;div id=&quot;cc_avis_wrap&quot; class=&quot;flex-row&quot;&gt;<br/>			       &lt;?php while ( $query-&gt;have_posts() ) : $query-&gt;the_post(); <br/>					$taxonomies = array(&#039;categories-avis&#039;,&#039;niveau-avis&#039;);<br/>					$termsArray = wp_get_object_terms($post-&gt;ID, $taxonomies, array( &#039;orderby&#039; =&gt; &#039;term_order&#039; ) );  <br/>					$termsString = &quot;&quot;; <br/>					foreach ( $termsArray as $term ) {  <br/>					$termsString .= $term-&gt;slug.&#039; &#039;; <br/>					}</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Tout à la fin de mon fichier, j&rsquo;ajoute mon bouton <em>ajax load more</em> :</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;?php	<br/>				 <br/>			if (  $query-&gt;max_num_pages &gt; 1 ) :<br/>				echo &#039;&lt;div class=&quot;loadmore_block&quot;&gt;&lt;div id=&quot;cc_avis_loadmore&quot;&gt;Afficher plus d\&#039;avis&lt;/div&gt;&lt;/div&gt;&#039;; // you can use &lt;a&gt; as well<br/>			endif;</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Juste après j&rsquo;appelle mon fichier js qui va contenir mes fonctions pour les filtres et le bouton <em>loadmore</em>, et je défini ici mes variables pour l&rsquo;ajax;</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;script&gt;<br/>	var posts_myajax_avis = &#039;&lt;?php echo serialize( $query-&gt;query_vars ) ?&gt;&#039;,<br/>    current_page_myajax_avis = 1,<br/>    max_page_myajax_avis = &lt;?php echo $query-&gt;max_num_pages ?&gt;<br/>&lt;/script&gt;<br/>&lt;script src=&quot;&lt;?php bloginfo(&#039;template_url&#039;)?&gt;/js/load-more-avis.js&quot;&gt;&lt;/script&gt;</code></pre> <div class="code-embed-infos"> </div> </div>
<h3>Les fonctions php</h3>
<p>Dans un fichier à part, que j&rsquo;appellerai avis-query.php, je crée ma fonction pour les filtres. Tout est décomposé ici pour rendre les choses plus claires. Je crée mes conditions pour chaque cas d&rsquo;utilisation.</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;?php <br/>add_action(&#039;wp_ajax_ccavisfilter&#039;, &#039;cc_avis_filter_function&#039;); <br/>add_action(&#039;wp_ajax_nopriv_ccavisfilter&#039;, &#039;cc_avis_filter_function&#039;);<br/> <br/><br/><br/>function cc_avis_filter_function(){<br/><br/>	if( isset( $_POST[&#039;all_categ&#039;] ) || isset( $_POST[&#039;all_niveau&#039;] )){<br/>		$niveau = get_terms( array( &#039;taxonomy&#039; =&gt; &#039;niveau-avis&#039; ) );<br/>		$categ = get_terms( array( &#039;taxonomy&#039; =&gt; &#039;categories-avis&#039; ) );<br/>    	$args=array(<br/>			&#039;post_type&#039;             =&gt; &#039;avis&#039;,<br/>		    &#039;posts_per_page&#039;        =&gt; 5,<br/>		    &#039;tax_query&#039; =&gt; array(<br/>	        &#039;relation&#039; =&gt; &#039;OR&#039;,<br/>        array(<br/>            &#039;taxonomy&#039; =&gt; &#039;categories-avis&#039;,<br/>            &#039;field&#039;    =&gt; &#039;term_id&#039;,<br/>            &#039;terms&#039;    =&gt; $categ,<br/>        ),<br/>        array(<br/>            &#039;taxonomy&#039; =&gt; &#039;niveau-avis&#039;,<br/>            &#039;field&#039;    =&gt; &#039;term_id&#039;,<br/>            &#039;terms&#039;    =&gt; $niveau ,<br/>        ),<br/>        ),<br/>		    );<br/>		<br/>	}<br/>	if( isset( $_POST[&#039;all_categ&#039;] ) &amp;&amp; isset( $_POST[&#039;all_niveau&#039;] )){<br/>		$niveau = get_terms( array( &#039;taxonomy&#039; =&gt; &#039;niveau-avis&#039; ) );<br/>		$categ = get_terms( array( &#039;taxonomy&#039; =&gt; &#039;categories-avis&#039; ) );<br/>    	$args=array(<br/>			&#039;post_type&#039;             =&gt; &#039;avis&#039;,<br/>		    &#039;posts_per_page&#039;        =&gt; 5,<br/>		    &#039;tax_query&#039; =&gt; array(<br/>	        &#039;relation&#039; =&gt; &#039;AND&#039;,<br/>        array(<br/>            &#039;taxonomy&#039; =&gt; &#039;categories-avis&#039;,<br/>            &#039;field&#039;    =&gt; &#039;term_id&#039;,<br/>            &#039;terms&#039;    =&gt; $categ,<br/>        ),<br/>        array(<br/>            &#039;taxonomy&#039; =&gt; &#039;niveau-avis&#039;,<br/>            &#039;field&#039;    =&gt; &#039;term_id&#039;,<br/>            &#039;terms&#039;    =&gt; $niveau ,<br/>        ),<br/>        ),<br/>		    );<br/>		<br/>	}	<br/>	// for taxonomies / categories<br/>	if( isset( $_POST[&#039;category_avis_filters&#039;] ) || isset( $_POST[&#039;niveau_avis_filters&#039;] )){<br/>		$args=array(<br/>			&#039;post_type&#039;             =&gt; &#039;avis&#039;,<br/>		    &#039;posts_per_page&#039;        =&gt; 5,<br/>		    &#039;tax_query&#039; =&gt; array(<br/>	        &#039;relation&#039; =&gt; &#039;OR&#039;,<br/>        array(<br/>            &#039;taxonomy&#039; =&gt; &#039;categories-avis&#039;,<br/>            &#039;field&#039;    =&gt; &#039;term_id&#039;,<br/>            &#039;terms&#039;    =&gt; $_POST[&#039;category_avis_filters&#039;],<br/>        ),<br/>        array(<br/>            &#039;taxonomy&#039; =&gt; &#039;niveau-avis&#039;,<br/>            &#039;field&#039;    =&gt; &#039;term_id&#039;,<br/>            &#039;terms&#039;    =&gt; $_POST[&#039;niveau_avis_filters&#039;],<br/>        ),<br/>        ),<br/>		    );<br/>		<br/>	}<br/> 		if( isset( $_POST[&#039;category_avis_filters&#039;] ) &amp;&amp; isset( $_POST[&#039;niveau_avis_filters&#039;] )){<br/>		$args=array(<br/>			&#039;post_type&#039;             =&gt; &#039;avis&#039;,<br/>		    &#039;posts_per_page&#039;        =&gt; 5,<br/>		    &#039;tax_query&#039; =&gt; array(<br/>	        &#039;relation&#039; =&gt; &#039;AND&#039;,<br/>        array(<br/>            &#039;taxonomy&#039; =&gt; &#039;categories-avis&#039;,<br/>            &#039;field&#039;    =&gt; &#039;term_id&#039;,<br/>            &#039;terms&#039;    =&gt; $_POST[&#039;category_avis_filters&#039;],<br/>        ),<br/>        array(<br/>            &#039;taxonomy&#039; =&gt; &#039;niveau-avis&#039;,<br/>            &#039;field&#039;    =&gt; &#039;term_id&#039;,<br/>            &#039;terms&#039;    =&gt; $_POST[&#039;niveau_avis_filters&#039;],<br/>        ),<br/>        ),<br/>		    );<br/>		<br/>	}<br/><br/><br/>	<br/><br/>	$query = new WP_Query( $args ); <br/>	if ( $query-&gt;have_posts() ) : <br/> 		  <br/> 		ob_start(); <br/> 		while ( $query-&gt;have_posts() ) : $query-&gt;the_post();<br/>			<br/>					$taxonomies = get_object_taxonomies( array( &#039;post_type&#039; =&gt; &#039;avis&#039;) );<br/>					$termsArray = get_the_terms( $post-&gt;ID, $taxonomies );  <br/>					$termsString = &quot;&quot;; <br/>					foreach ( $termsArray as $term ) { <br/>					$termsString .= $term-&gt;slug.&#039; &#039;; <br/>					}<br/>					?&gt; <br/><br/>&lt;?php // ici le html/php pour mes articles ?&gt;<br/><br/>&lt;?php<br/>		endwhile;<br/> 		$posts_html = ob_get_contents(); <br/>   		ob_end_clean(); <br/>	else:<br/>		$posts_html = &#039;&lt;p&gt;Aucun résultat.&lt;/p&gt;&#039;;<br/>	endif;<br/> 	echo json_encode( array(<br/>		&#039;posts&#039; =&gt; json_encode( $query-&gt;query_vars ),<br/>		&#039;max_page&#039; =&gt; $query-&gt;max_num_pages,<br/>		&#039;found_posts&#039; =&gt; $query-&gt;found_posts,<br/>		&#039;content&#039; =&gt; $posts_html<br/>	) );<br/>	die();<br/>}</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Ici je fais en sorte qu&rsquo;on puisse sélectionner une catégorie et un niveau par catégorie, OU, un niveau et une catégorie par niveau.</p>
<h3>Les fonction js</h3>
<p>Dans un fichier js à part, que je nomme <em>load-more-avis.js</em>, je crée donc mes deux fonctions : une pour le bouton load more, et l&rsquo;autre pour les filtres.</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">jQuery(function($){<br/><br/> /* LOAD MORE FUNCTION ON avis ARCHIVE PAGE */<br/>  $(&#039;#cc_avis_loadmore&#039;).click(function(){<br/> <br/>     data = {<br/>      &#039;action&#039;: &#039;loadmoreavisbutton&#039;,<br/>      &#039;query&#039;: posts_myajax_avis,<br/>      &#039;page&#039; : current_page_myajax_avis<br/>    };<br/> <br/>    $.ajax({<br/>      url : &#039;/numgrade/wp-admin/admin-ajax.php&#039;, // AJAX handler<br/>      data : data,<br/>      type : &#039;POST&#039;,<br/>      beforeSend : function ( xhr ) {<br/>        $(&#039;#cc_avis_loadmore&#039;).text(&#039;Recherche...&#039;); // some type of preloader<br/>      },<br/>      success : function( posts ){<br/>        if( posts ) {<br/> <br/>          $(&#039;#cc_avis_loadmore&#039;).text( &#039;Afficher plus d\&#039;avis&#039; );<br/>          $(&#039;#cc_avis_wrap&#039;).append( posts ); // insert new posts<br/>         current_page_myajax_avis++;<br/> <br/>          if ( current_page_myajax_avis == max_page_myajax_avis )<br/>            $(&#039;#cc_avis_loadmore&#039;).hide(); // if last page, HIDE the button<br/> <br/>        } else {<br/>          $(&#039;#cc_avis_loadmore&#039;).hide(); // if no data, HIDE the button as well<br/>        }<br/>      }<br/>    });<br/>    return false;<br/>  });<br/>/* FILTERING FUNCTION ON avis ARCHIVE PAGE */<br/>  $(&#039;#avis_filters&#039;).change(function(){<br/>    $.ajax({<br/>      url : &#039;/numgrade/wp-admin/admin-ajax.php&#039;,<br/>      data : $(&#039;#avis_filters&#039;).serialize(), // form data<br/>      dataType : &#039;json&#039;, // this data type allows us to receive objects from the server<br/>      type : &#039;POST&#039;,<br/><br/>      success : function( data ){<br/>        // when filter applied:<br/>        // set the current page to 1<br/>        current_page_myajax_avis = 1; <br/>        // set the new query parameters<br/>        posts_myajax_avis = data.posts;<br/>        // set the new max page parameter<br/>        max_page_myajax_avis = data.max_page; <br/>        // change the button label back<br/>        // insert the posts to the container<br/>        $(&#039;#cc_avis_wrap&#039;).html(data.content); <br/>        // hide load more button, if there are not enough posts for the second page<br/>        if ( data.max_page &lt; 2 ) {<br/>          $(&#039;#cc_avis_loadmore&#039;).hide();<br/>        } else {<br/>          $(&#039;#cc_avis_loadmore&#039;).show();<br/>        }<br/>      }<br/>    });<br/>    // do not submit the form<br/>    return false;<br/> <br/>  });<br/><br/>});</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Maintenant, quelque soit le choix de l&rsquo;utilisateur, le bouton load-more ne chargera que la suite des articles de la catégorie et du niveau sélectionnés.</p>
<p>The post <a rel="nofollow" href="https://www.copier-coller.com/systeme-de-filtres-avances-pour-custom-post-type/">Système de filtres avancés pour custom post type</a> appeared first on <a rel="nofollow" href="https://www.copier-coller.com">Copier coller</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.copier-coller.com/systeme-de-filtres-avances-pour-custom-post-type/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Filtrer ses custom post type et ajouter un bouton load more</title>
		<link>https://www.copier-coller.com/filtrer-ses-custom-post-type-et-ajouter-un-bouton-load-more/</link>
					<comments>https://www.copier-coller.com/filtrer-ses-custom-post-type-et-ajouter-un-bouton-load-more/#respond</comments>
		
		<dc:creator><![CDATA[copier coller]]></dc:creator>
		<pubDate>Mon, 20 Apr 2020 18:48:39 +0000</pubDate>
				<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://www.copier-coller.com/?p=6100</guid>

					<description><![CDATA[<p>Dans un précédent article, j&#8217;ai montré un exemple d&#8217;implémentation, à partir des articles classiques, d&#8217;une fonction de filtrage et de rechargement en ajax des articles. Ici on va voir comment pousser encore plus loin ce système en l&#8217;étendant aux custom post type. Voici un rendu possible : on a nos différents filtres tout en haut, [...]</p>
<p>The post <a rel="nofollow" href="https://www.copier-coller.com/filtrer-ses-custom-post-type-et-ajouter-un-bouton-load-more/">Filtrer ses custom post type et ajouter un bouton load more</a> appeared first on <a rel="nofollow" href="https://www.copier-coller.com">Copier coller</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Comment rajouter des filtres et un bouton load more à ses custom post type ?</h2>
<p>Dans un <a href="https://www.copier-coller.com/filtrer-ses-articles-et-ajouter-un-bouton-loadmore/">précédent article</a>, j&rsquo;ai montré un exemple d&rsquo;implémentation, à partir des articles classiques, d&rsquo;une fonction de filtrage et de rechargement en ajax des articles.</p>
<p>Ici on va voir comment pousser encore plus loin ce système en l&rsquo;étendant aux custom post type. Voici un rendu possible : on a nos différents filtres tout en haut, et un bouton de rechargement d&rsquo;articles en ajax tout en bas.</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6102" src="https://www.copier-coller.com/wp-content/uploads/2020/04/filtres-cpt-wordpress.png" alt="filtres cpt wordpress" width="679" height="718" srcset="https://www.copier-coller.com/wp-content/uploads/2020/04/filtres-cpt-wordpress.png 679w, https://www.copier-coller.com/wp-content/uploads/2020/04/filtres-cpt-wordpress-284x300.png 284w, https://www.copier-coller.com/wp-content/uploads/2020/04/filtres-cpt-wordpress-624x660.png 624w" sizes="(max-width: 679px) 100vw, 679px" /></p>
<h3>Création du custom post type</h3>
<p>Je pars du même exemple que précédemment : je crée un custom post type appelé « formation ». Je lui attribue deux taxonomies : « <em>categorie-formations »</em> et « <em>niveau-formation</em>« . Ces taxonomies ont comme argument : &lsquo;<strong><em>hierarchical&rsquo; =&gt; true »</em></strong>, : cela permet entre autre d&rsquo;avoir des cases à cocher dans le backoffice, comme pour des catégories classiques.</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;?php<br/>function cc_formation_cpt() {<br/>	/* Formation */<br/>	$labels = array(<br/>		&#039;name&#039;                =&gt; _x(&#039;Formations&#039;, &#039;Post Type General Name&#039;, &#039;text_domain&#039;),<br/>		&#039;singular_name&#039;       =&gt; _x(&#039;Formation&#039;, &#039;Post Type Singular Name&#039;, &#039;text_domain&#039;),<br/>		&#039;menu_name&#039;           =&gt; _x(&#039;Formations&#039;, &#039;text_domain&#039;),<br/>		&#039;name_admin_bar&#039;      =&gt; _x(&#039;Formations&#039;, &#039;text_domain&#039;),<br/>		&#039;all_items&#039;           =&gt; _x(&#039;Toutes les formations&#039;, &#039;text_domain&#039;),<br/>		&#039;add_new_item&#039;        =&gt; _x(&#039;Ajouter une nouvelle formation&#039;, &#039;text_domain&#039;),<br/>		&#039;add_new&#039;             =&gt; _x(&#039;Ajouter&#039;, &#039;text_domain&#039;),<br/>		&#039;new_item&#039;            =&gt; _x(&#039;Nouvelle formation&#039;, &#039;text_domain&#039; ),<br/>		&#039;edit_item&#039;           =&gt; _x(&#039;Editer la formation&#039;, &#039;text_domain&#039;),<br/>		&#039;update_item&#039;         =&gt; _x(&#039;Mettre à jour la formation&#039;, &#039;text_domain&#039;),<br/>		&#039;view_item&#039;           =&gt; _x(&#039;Voir la formation&#039;, &#039;text_domain&#039;),<br/>		&#039;search_items&#039;        =&gt; _x(&#039;Rechercher une formation&#039;, &#039;text_domain&#039;),<br/>		&#039;not_found&#039;           =&gt; _x(&#039;Aucune formation trouvée&#039;, &#039;text_domain&#039;),<br/>		&#039;not_found_in_trash&#039;  =&gt; _x(&#039;Aucune formation trouvée dans la corbeille&#039;, &#039;text_domain&#039;),<br/>	);<br/>	<br/>	$args = array(<br/>		&#039;label&#039;               =&gt; _x(&#039;Formation&#039;, &#039;text_domain&#039;),<br/>		&#039;description&#039;         =&gt; _x(&#039;Formations&#039;, &#039;text_domain&#039;),<br/>		&#039;labels&#039;              =&gt; $labels,<br/>		&#039;supports&#039;            =&gt; array(&#039;title&#039;, &#039;editor&#039;, &#039;thumbnail&#039;, &#039;comments&#039;, &#039;revisions&#039;, &#039;custom-fields&#039;),<br/>		&#039;hierarchical&#039;        =&gt; false,<br/>		&#039;public&#039;              =&gt; true,<br/>		&#039;show_ui&#039;             =&gt; true,<br/>		&#039;show_in_menu&#039;        =&gt; true,<br/>		&#039;menu_position&#039;       =&gt; 5,<br/>		&#039;menu_icon&#039;           =&gt; &#039;dashicons-admin-home&#039;,<br/>		&#039;show_in_admin_bar&#039;   =&gt; true,<br/>		&#039;show_in_nav_menus&#039;   =&gt; true,<br/>		&#039;can_export&#039;          =&gt; true,<br/>		&#039;has_archive&#039;         =&gt; false,<br/>		&#039;exclude_from_search&#039; =&gt; false,<br/>		&#039;publicly_queryable&#039;  =&gt; true,<br/>		&#039;query_var&#039;           =&gt; true,<br/>		&#039;rewrite&#039;             =&gt;  array( &#039;slug&#039; =&gt; &#039;toutes-nos-formations&#039; ),<br/>		&#039;capability_type&#039;     =&gt; &#039;post&#039;,<br/>		&#039;show_in_rest&#039;			=&gt;&#039;true&#039;,<br/>	);<br/>	register_post_type(&#039;formation&#039;, $args);	<br/>}<br/>add_action(&#039;init&#039;, &#039;cc_formation_cpt&#039;, 10);<br/><br/><br/><br/>function cc_formation_category_taxonomies() {<br/><br/>	$labels_cat_formation = array(<br/>		&#039;name&#039;                       =&gt; _x( &#039;Catégories de la formation&#039;, &#039;taxonomy general name&#039;),<br/>		&#039;singular_name&#039;              =&gt; _x( &#039;Catégories de la formation&#039;, &#039;taxonomy singular name&#039;),<br/>		&#039;search_items&#039;               =&gt; __( &#039;Rechercher une catégorie&#039;),<br/>		&#039;popular_items&#039;              =&gt; __( &#039;Catégories populaires&#039;),<br/>		&#039;all_items&#039;                  =&gt; __( &#039;Toutes les catégories&#039;),<br/>		&#039;edit_item&#039;                  =&gt; __( &#039;Editer une catégorie&#039;),<br/>		&#039;update_item&#039;                =&gt; __( &#039;Mettre à jour une catégorie&#039;),<br/>		&#039;add_new_item&#039;               =&gt; __( &#039;Ajouter une nouvelle catégorie&#039;),<br/>		&#039;new_item_name&#039;              =&gt; __( &#039;Nom de la nouvelle catégorie&#039;),<br/>		&#039;add_or_remove_items&#039;        =&gt; __( &#039;Ajouter ou supprimer une catégorie&#039;),<br/>		&#039;choose_from_most_used&#039;      =&gt; __( &#039;Choisir parmi les catégories les plus utilisées&#039;),<br/>		&#039;not_found&#039;                  =&gt; __( &#039;Pas de catégories trouvée&#039;),<br/>		&#039;menu_name&#039;                  =&gt; __( &#039;Catégorie de formation&#039;),<br/>	);<br/><br/>	$args_cat_formation = array(<br/>		&#039;hierarchical&#039;          =&gt; true,<br/>		&#039;labels&#039;                =&gt; $labels_cat_formation,<br/>		&#039;show_ui&#039;               =&gt; true,<br/>		&#039;show_in_rest&#039;			=&gt; true,<br/>		&#039;show_admin_column&#039;     =&gt; true,<br/>		&#039;query_var&#039;             =&gt; true,<br/>		&#039;rewrite&#039;               =&gt; array( &#039;slug&#039; =&gt; &#039;categories-formations&#039; ),<br/>	);<br/><br/>	register_taxonomy( &#039;categories-formations&#039;, &#039;formation&#039;, $args_cat_formation );<br/>}<br/>add_action( &#039;init&#039;, &#039;cc_formation_category_taxonomies&#039;, 0 );<br/><br/>function cc_formation_level_taxonomies() {<br/><br/>	$labels_level_formation = array(<br/>		&#039;name&#039;                       =&gt; _x( &#039;Niveaux de la formation&#039;, &#039;taxonomy general name&#039;),<br/>		&#039;singular_name&#039;              =&gt; _x( &#039;Niveau de la formation&#039;, &#039;taxonomy singular name&#039;),<br/>		&#039;search_items&#039;               =&gt; __( &#039;Rechercher un niveau&#039;),<br/>		&#039;popular_items&#039;              =&gt; __( &#039;Niveaux populaires&#039;),<br/>		&#039;all_items&#039;                  =&gt; __( &#039;Tous les Niveaux&#039;),<br/>		&#039;edit_item&#039;                  =&gt; __( &#039;Editer un niveau&#039;),<br/>		&#039;update_item&#039;                =&gt; __( &#039;Mettre à jour un niveau&#039;),<br/>		&#039;add_new_item&#039;               =&gt; __( &#039;Ajouter un nouveau niveau&#039;),<br/>		&#039;new_item_name&#039;              =&gt; __( &#039;Nom de le nouveau niveau&#039;),<br/>		&#039;add_or_remove_items&#039;        =&gt; __( &#039;Ajouter ou supprimer un niveau&#039;),<br/>		&#039;choose_from_most_used&#039;      =&gt; __( &#039;Choisir parmi les nivexau les plus utilisées&#039;),<br/>		&#039;not_found&#039;                  =&gt; __( &#039;Pas de niveau trouvé&#039;),<br/>		&#039;menu_name&#039;                  =&gt; __( &#039;Niveau de formation&#039;),<br/>	);<br/><br/>	$args_level_formation = array(<br/>	<br/>		&#039;hierarchical&#039;          =&gt; true,<br/>		&#039;labels&#039;                =&gt; $labels_level_formation,<br/>		&#039;show_ui&#039;               =&gt; true,<br/>		&#039;show_in_rest&#039;			=&gt; true,<br/>		&#039;show_admin_column&#039;     =&gt; true,<br/>		&#039;query_var&#039;             =&gt; true,<br/>		&#039;rewrite&#039;               =&gt; array( &#039;slug&#039; =&gt; &#039;niveau-formations&#039; ),<br/>	);<br/><br/>	register_taxonomy( &#039;niveau-formations&#039;, &#039;formation&#039;, $args_level_formation );<br/>}<br/>add_action( &#039;init&#039;, &#039;cc_formation_level_taxonomies&#039;, 0 );</code></pre> <div class="code-embed-infos"> </div> </div>
<h3>Une page d&rsquo;archive pour le custom post type</h3>
<p>Je crée ensuite ma page d&rsquo;archive <strong><em>page-formation.php</em></strong> pour mon custom post type. Normalement, en passant l&rsquo;argument <strong><em>has_archive</em></strong> à <strong><em>true</em></strong>, wordpress va automatiquement générer une page d&rsquo;archive pour notre custom post type. Il suffira alors d&rsquo;aller la chercher dans <strong>Apparence / Menu</strong> et de la placer dans le menu. Le problème c&rsquo;est que cette page est « fictive », dans le sens où elle n&rsquo;existe pas en dur dans le dossier wordpress. On ne peut donc pas l&rsquo;administrer.</p>
<p>Dans mon exemple, j&rsquo;ai forcément besoin de pouvoir la personnaliser puisque je veux y inclure mon système de filtre et le bouton ajax load more. Je veux aussi donner la possibilité à l&rsquo;utilisateur final de pouvoir intervenir dessus. Après le bloc de filtre et la boucle pour mes custom post type, je replace donc un <strong><em>the_content(),</em></strong> ce qui va lui permettre d&rsquo;éditer la page via l&rsquo;éditeur classique de wordpress, ou tout autre page builder.</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;?php<br/>/**<br/> * Template Name: Toutes nos Formations<br/> *<br/> * @link https://developer.wordpress.org/themes/basics/template-hierarchy/<br/> <br/> *<br/> */<br/>get_header();<br/>?&gt;<br/><br/>&lt;div id=&quot;primary&quot; class=&quot;content-area&quot;&gt;<br/>	&lt;main id=&quot;main&quot; class=&quot;site-main&quot;&gt;<br/>		&lt;div class=&quot;flex-container&quot;&gt;<br/>			&lt;div class=&quot;flex-row&quot;&gt;	<br/>				&lt;header class=&quot;page-header&quot;&gt;<br/>					&lt;h1 class=&quot;archive_title&quot;&gt;&lt;?php  // Ici je ramène deux champs additionnels crées avec ACF, afin de laisser l&#039;utilisateur indiquer un titre et une description personnalisée à mon modèle de page<br/>					if(get_field(&#039;titre&#039;))<br/>					{<br/>						echo &#039;&lt;p&gt;&#039; . get_field(&#039;titre&#039;) . &#039;&lt;/p&gt;&#039;;<br/>					}<br/>					?&gt;<br/>					&lt;/h1&gt;<br/>					&lt;h2&gt;<br/>					&lt;?php  if(get_field(&#039;description&#039;)){<br/>						echo &#039;&lt;p&gt;&#039; . get_field(&#039;description&#039;) . &#039;&lt;/p&gt;&#039;;<br/>					} ?&gt;<br/>				     &lt;/h2&gt;<br/>					<br/>				&lt;/header&gt;&lt;!-- .page-header --&gt;<br/>			&lt;/div&gt;<br/>			&lt;div class=&quot;flex-row&quot;&gt; &lt;?php // Voici le formulaire de filtrage. On boucle directement sur les taxonomie de mon custom post type ?&gt;<br/>				&lt;form action=&quot;#&quot; method=&quot;POST&quot; id=&quot;formation_filters&quot;&gt;<br/>					&lt;p&gt;&lt;input type=&quot;radio&quot; value=&quot;all&quot; id=&quot;all&quot; class=&quot;category_filter&quot; name=&quot;category_formation_filters&quot;&gt;&lt;label for=&quot;all&quot;&gt;Toutes&lt;/label&gt;&lt;/p&gt;<br/>										<br/>					&lt;?php <br/>					if( $terms = get_terms( array( &#039;taxonomy&#039; =&gt; &#039;categories-formations&#039; ) ) ) :<br/>						foreach( $terms as $term ) :<br/>							echo &#039;&lt;p&gt;&lt;input type=&quot;radio&quot; id=&quot;&#039; . $term-&gt;term_id . &#039;&quot; value=&quot;&#039; . $term-&gt;term_id . &#039;&quot; name=&quot;category_formation_filters&quot; class=&quot;category_formation_filters&quot;/&gt;&lt;label for=&quot;&#039; . $term-&gt;term_id. &#039;&quot;&gt;&#039; . $term-&gt;name . &#039;&lt;/label&gt;&lt;/p&gt;&#039;;<br/>						endforeach;<br/>					endif;<br/>					?&gt;<br/>					&lt;!-- required hidden field for admin-ajax.php --&gt;<br/>					&lt;input type=&quot;hidden&quot; name=&quot;action&quot; value=&quot;ccformationfilter&quot; /&gt;<br/>				&lt;/form&gt;<br/>			&lt;/div&gt;<br/>		   &lt;?php <br/>			// ma boucle qui me ramène tous les custom post type &quot;formation&quot;<br/>			$paged = (get_query_var(&#039;paged&#039;)) ? get_query_var(&#039;paged&#039;) : 1;<br/>			$args=array(<br/>			&#039;post_type&#039; =&gt;&#039;formation&#039;,<br/>			&#039;posts_per_page&#039; =&gt;5,<br/>			&#039;paged&#039; =&gt; $paged<br/><br/>			);<br/>			$query = new WP_Query( $args );  ?&gt;<br/>			&lt;?php if ( $query-&gt;have_posts() ) : ?&gt;<br/>		    &lt;div id=&quot;cc_formation_wrap&quot; class=&quot;flex-row&quot;&gt;<br/>			    &lt;?php while ( $query-&gt;have_posts() ) : $query-&gt;the_post(); <br/>					$termsArray = get_the_terms( $post-&gt;ID, &quot;categories-formations&quot; );  // On récupère la taxonomy<br/>					$termsString = &quot;&quot;; <br/>					foreach ( $termsArray as $term ) { <br/>					$termsString .= $term-&gt;slug.&#039; &#039;; <br/>					}<br/>					?&gt; <br/>					&lt;div class=&quot;&lt;?php echo $termsString;?&gt; flex-col-sm-6 flex-col-md-4 item&quot;&gt;<br/>					&lt;article  id=&quot;post-&lt;?php the_ID(); ?&gt;&quot; &lt;?php post_class(&#039;related-formation-post&#039;);?&gt;&gt;<br/>						&lt;div class=&quot;isotope-thumbnail&quot;&gt;<br/>					     &lt;?php <br/>					    	if ( has_post_thumbnail() ) { <br/>					                      the_post_thumbnail(&#039;masonryLayout&#039;);<br/>					                } ;<br/>							?&gt;<br/>						&lt;/div&gt;<br/>						&lt;div class=&quot;isotope-title&quot;&gt;<br/>							&lt;?php<br/>									the_title( &#039;&lt;h2 class=&quot;entry-title&quot;&gt;&lt;a href=&quot;&#039; . esc_url( get_permalink() ) . &#039;&quot; rel=&quot;bookmark&quot;&gt;&#039;, &#039;&lt;/a&gt;&lt;/h2&gt;&#039; );<br/>								?&gt;<br/>						&lt;/div&gt;<br/>						&lt;div class=&quot;entry-meta&quot;&gt;<br/>								&lt;?php	 if(get_field(&#039;duree&#039;)){ 	<br/>									$duree = get_field_object(&#039;duree&#039;);<br/>									echo &#039;&lt;div&gt;&lt;span class=&quot;isotope-duree&quot;&gt;&#039; .  get_field(&#039;duree&#039;) . &#039;&lt;/span&gt;&lt;/div&gt;&#039;;<br/>									}<br/>								?&gt;<br/>							&lt;/div&gt;<br/>						&lt;div class=&quot;isotope-excerpt&quot;&gt;<br/>							&lt;?php echo get_post_meta(get_the_ID(), &#039;_yoast_wpseo_metadesc&#039;, true); ?&gt;<br/>						&lt;/div&gt;<br/>						&lt;div class=&quot;isotope-cta&quot;&gt;<br/>							&lt;a href=&quot;&lt;?php esc_url( the_permalink() );?&gt;&quot; rel=&quot;bookmark&quot;&gt;Voir&lt;/a&gt;<br/>						&lt;/div&gt;<br/>					&lt;/article&gt;<br/>				 &lt;/div&gt; &lt;!-- end item --&gt;<br/><br/>		    	&lt;?php endwhile;  <br/>		    	?&gt;<br/>		    &lt;/div&gt; &lt;!-- end isotope-list --&gt;<br/>		<br/>			&lt;?php	<br/>				 <br/>			if (  $query-&gt;max_num_pages &gt; 1 ) :<br/>				echo &#039;&lt;div class=&quot;loadmore_block&quot;&gt;&lt;div id=&quot;cc_formation_loadmore&quot;&gt;Afficher plus de formations&lt;/div&gt;&lt;/div&gt;&#039;; // you can use &lt;a&gt; as well<br/>			endif;<br/>		<br/>			else :<br/>			get_template_part( &#039;template-parts/content&#039;, &#039;none&#039; );<br/>			endif;	<br/>			?&gt;<br/>		&lt;/div&gt;&lt;!-- .flex-container --&gt;<br/><br/>		&lt;?php<br/>		// hack : je replace ici the content(), pour laisser l&#039;utilisateur administrer cette partie de la page<br/>		<br/>		if ( have_posts() ) :<br/>			while ( have_posts() ) : the_post();<br/>			the_content();<br/>			endwhile; <br/>			endif;		<br/>		;?&gt;<br/>	&lt;/main&gt;&lt;!-- #main --&gt;<br/>&lt;/div&gt;&lt;!-- #primary --&gt;<br/>&lt;?php  // les variables qui vont servir l&#039;ajax ?&gt;<br/>&lt;script&gt;<br/>	var posts_myajax = &#039;&lt;?php echo serialize( $query-&gt;query_vars ) ?&gt;&#039;,<br/>    current_page_myajax = 1,<br/>    max_page_myajax = &lt;?php echo $query-&gt;max_num_pages ?&gt;<br/>&lt;/script&gt;<br/>&lt;script src=&quot;&lt;?php bloginfo(&#039;template_url&#039;)?&gt;/js/load-more.js&quot;&gt;&lt;/script&gt;<br/>&lt;?php get_footer();?&gt;</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Ici, il faut faire attention aux éléments suivants :</p>
<ul>
<li>L&rsquo;id du formulaire : #<em><strong>formation_filters</strong></em></li>
<li>Le nom du bouton radio qui va nous permettre de récupérer la sélection de l&rsquo;utilisateur : <strong><em>name= »category_formation_filters »</em></strong></li>
<li>La valeur du champ caché pour l&rsquo;envoi du formulaire : <strong><em>value= »ccformationfilter » </em></strong>qui devra correspondre au nom de mon action ajax pour les filtres.</li>
</ul>
<p>Contrairement au <a href="https://www.copier-coller.com/filtrer-ses-articles-et-ajouter-un-bouton-loadmore/">précédent article</a>, les variables servant <strong><em>wp_localize_script</em></strong> ne sont pas injectés via le fichier <strong><em>functions.php</em></strong>, mais directement à la fin de mon fichier <strong><em>page-formation.php. </em></strong>Ce sont ces variables qui seront utilisées dans le fichier js, donc attention à la nomenclature !</p>
<p>L&rsquo;appel au fichier js qui va contenir tout le code est aussi appelé directement depuis cette page.</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;script&gt;<br/>	var posts_myajax = &#039;&lt;?php echo serialize( $query-&gt;query_vars ) ?&gt;&#039;,<br/>    current_page_myajax = 1,<br/>    max_page_myajax = &lt;?php echo $query-&gt;max_num_pages ?&gt;<br/>&lt;/script&gt;<br/>&lt;script src=&quot;&lt;?php bloginfo(&#039;template_url&#039;)?&gt;/js/load-more.js&quot;&gt;&lt;/script&gt;</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Ainsi, en changeant juste le nom des variables et en créant un fichier distinct, vous pourrez étendre ce système à tous vos custom post types !</p>
<h3>Création du fichier formation-query.php</h3>
<p>Dans un dossier à part, je crée un nouveau fichier php que j&rsquo;appelle <strong><em>formation-query.php</em></strong>. Vous pouvez évidemment lui attribuer le nom de votre choix.</p>
<p>Dans le fichier <strong><em>functions.php</em></strong>, je l&rsquo;inclue avec un <strong><em>require </em></strong>:</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">/**<br/> * Formation query<br/> */<br/><br/>require get_template_directory() . &#039;/inc/formation-query.php&#039;;</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Ce fichier va contenir deux grandes fonctions et deux boucles, l&rsquo;une pour les filtres, l&rsquo;autre pour le bouton <em>ajax load more</em>. On reprend la même logique que pour les articles de blogs de mon précédent article, mais on sépare à présent les fichiers pour une arborescence plus propre, et un code plus facilement maintenable.</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;?php <br/><br/>add_action(&#039;wp_ajax_loadmoreformationbutton&#039;, &#039;cc_formation_loadmore_ajax_handler&#039;);<br/>add_action(&#039;wp_ajax_nopriv_loadmoreformationbutton&#039;, &#039;cc_formation_loadmore_ajax_handler&#039;);<br/> <br/>function cc_formation_loadmore_ajax_handler(){<br/><br/>	$args = json_decode( stripslashes( $_POST[&#039;query&#039;] ), true ); <br/>	$args[&#039;paged&#039;] = $_POST[&#039;page&#039;] + 1; <br/>	$args[&#039;post_status&#039;] = &#039;publish&#039;;<br/>	$args[&quot;post_type&quot;] = &#039;formation&#039;;<br/>	query_posts( $args );<br/>	global $wp_query;<br/>	if( have_posts() ) :<br/> 		while( have_posts() ): the_post();<br/>			$termsArray = get_the_terms($post-&gt;ID, &quot;categories-formations&quot;);  <br/>			 $termsString =&quot;&quot;; <br/>			 foreach ( $termsArray as $term ) {<br/>			 $termsString .= $term-&gt;slug;  <br/>			 }<br/>			 ?&gt;<br/> 			&lt;div class=&quot;&lt;?php echo $termsString;?&gt; flex-col-sm-6 flex-col-md-4 item&quot;&gt;<br/>				&lt;article  id=&quot;post-&lt;?php the_ID(); ?&gt;&quot; &lt;?php post_class(&#039;related-formation-post&#039;);?&gt;&gt;<br/>					&lt;div class=&quot;isotope-thumbnail&quot;&gt;<br/>				     &lt;?php <br/>				    	if ( has_post_thumbnail() ) { <br/>				                      the_post_thumbnail(&#039;masonryLayout&#039;);<br/>				                } ;<br/>						?&gt;<br/>					&lt;/div&gt;<br/>					&lt;div class=&quot;isotope-title&quot;&gt;<br/>						&lt;?php the_title( &#039;&lt;h2 class=&quot;entry-title&quot;&gt;&lt;a href=&quot;&#039; . esc_url( get_permalink() ) . &#039;&quot; rel=&quot;bookmark&quot;&gt;&#039;, &#039;&lt;/a&gt;&lt;/h2&gt;&#039; );?&gt;<br/>					&lt;/div&gt;<br/>					&lt;div class=&quot;isotope-excerpt&quot;&gt;<br/>						&lt;?php echo get_post_meta(get_the_ID(), &#039;_yoast_wpseo_metadesc&#039;, true); ?&gt;<br/>					&lt;/div&gt;<br/>					&lt;div class=&quot;isotope-cta&quot;&gt;<br/>						&lt;a href=&quot;&lt;?php esc_url( the_permalink() );?&gt;&quot; rel=&quot;bookmark&quot;&gt;Voir&lt;/a&gt;<br/>					&lt;/div&gt;<br/>				&lt;/article&gt;<br/>			 &lt;/div&gt; &lt;!-- end item --&gt;<br/>			&lt;?php<br/>		endwhile;<br/>	endif;<br/>	die; <br/>}<br/> <br/>add_action(&#039;wp_ajax_ccformationfilter&#039;, &#039;cc_formation_filter_function&#039;); <br/>add_action(&#039;wp_ajax_nopriv_ccformationfilter&#039;, &#039;cc_formation_filter_function&#039;);<br/> <br/><br/><br/>function cc_formation_filter_function(){<br/><br/>	if( isset( $_POST[&#039;all&#039;] ) )<br/>    	$terms = get_terms( array( &#039;taxonomy&#039; =&gt; &#039;categories-formations&#039; ) );<br/>            $args[&#039;tax_query&#039;] = array(<br/>                array(<br/>                    <br/>                    &#039;taxonomy&#039; =&gt; &#039;categories-formations&#039;,<br/>                    &#039;field&#039; =&gt; &#039;term_id&#039;,<br/>                    &#039;terms&#039; =&gt; $terms,<br/>                    &quot;posts_per_page&quot; =&gt; 5<br/>                )<br/>            );<br/><br/><br/><br/><br/><br/>	$args[&quot;post_type&quot;] = &#039;formation&#039;;<br/>		$args[&#039;tax_query&#039;] = array(<br/>			array(<br/>				&#039;taxonomy&#039; =&gt; &#039;categories-formations&#039;,<br/>				&#039;field&#039; =&gt; &#039;term_id&#039;,<br/>				&#039;terms&#039; =&gt; $_POST[&#039;category_formation_filters&#039;],<br/>				&quot;posts_per_page&quot; =&gt; 5<br/>			)<br/>		);<br/> <br/>	$query = new WP_Query($args);<br/>	if( $query-&gt;have_posts() ) :<br/> 		ob_start(); <br/> 		while( $query-&gt;have_posts() ): $query-&gt;the_post();<br/> 	<br/>			$termsArray = get_the_terms($post-&gt;ID, &quot;categories-formations&quot;);  <br/>			 $termsString =&quot;&quot;; <br/>			 foreach ( $termsArray as $term ) { <br/>			 $termsString .= $term-&gt;slug;  <br/>			 }<br/>			 ?&gt;<br/> 			&lt;div class=&quot;&lt;?php echo $termsString;?&gt; flex-col-sm-6 flex-col-md-4 item&quot;&gt;<br/>				&lt;article  id=&quot;post-&lt;?php the_ID(); ?&gt;&quot; &lt;?php post_class(&#039;related-formation-post&#039;);?&gt;&gt;<br/>					&lt;div class=&quot;isotope-thumbnail&quot;&gt;<br/>				     &lt;?php <br/>				    	if ( has_post_thumbnail() ) { <br/>				                      the_post_thumbnail(&#039;masonryLayout&#039;);<br/>				                } <br/>						?&gt;<br/>					&lt;/div&gt;<br/>					&lt;div class=&quot;isotope-title&quot;&gt;<br/>						&lt;?php the_title( &#039;&lt;h2 class=&quot;entry-title&quot;&gt;&lt;a href=&quot;&#039; . esc_url( get_permalink() ) . &#039;&quot; rel=&quot;bookmark&quot;&gt;&#039;, &#039;&lt;/a&gt;&lt;/h2&gt;&#039; );?&gt;<br/>					&lt;/div&gt;<br/>					&lt;div class=&quot;entry-meta&quot;&gt;<br/>							&lt;?php	 if(get_field(&#039;duree&#039;)){ 	<br/>								$duree = get_field_object(&#039;duree&#039;);<br/>								echo &#039;&lt;div&gt;&lt;span class=&quot;isotope-duree&quot;&gt;&#039; .  get_field(&#039;duree&#039;) . &#039;&lt;/span&gt;&lt;/div&gt;&#039;;<br/>								}<br/>							?&gt;<br/>						&lt;/div&gt;<br/>					&lt;div class=&quot;isotope-excerpt&quot;&gt;<br/>						&lt;?php echo get_post_meta(get_the_ID(), &#039;_yoast_wpseo_metadesc&#039;, true); ?&gt;<br/>					&lt;/div&gt;<br/>					&lt;div class=&quot;isotope-cta&quot;&gt;<br/>						&lt;a href=&quot;&lt;?php esc_url( the_permalink() );?&gt;&quot; rel=&quot;bookmark&quot;&gt;Voir&lt;/a&gt;<br/>					&lt;/div&gt;<br/>				&lt;/article&gt;<br/>			 &lt;/div&gt; &lt;!-- end item --&gt;<br/>			&lt;?php<br/>		endwhile;<br/> 		$posts_html = ob_get_contents(); <br/>   		ob_end_clean(); <br/>	else:<br/>		$posts_html = &#039;&lt;p&gt;Aucun résultat.&lt;/p&gt;&#039;;<br/>	endif;<br/> 	echo json_encode( array(<br/>		&#039;posts&#039; =&gt; json_encode( $query-&gt;query_vars ),<br/>		&#039;max_page&#039; =&gt; $query-&gt;max_num_pages,<br/>		&#039;found_posts&#039; =&gt; $query-&gt;found_posts,<br/>		&#039;content&#039; =&gt; $posts_html<br/>	) );<br/>	die();<br/>}</code></pre> <div class="code-embed-infos"> </div> </div>
<h4>Le bouton ajax load more</h4>
<p>Ici, mon action ajax s&rsquo;appelle: <em><strong>loadmoreformationbutton</strong></em></p>
<p>Dans ma fonction <strong><em>cc_formation_loadmore_ajax_handler</em></strong>, je crée la même boucle que dans mon modèle de page et custom post type <strong><em>page-formation.php.</em></strong></p>
<h4>Le sytème de filtre</h4>
<p>Pour mes filtres, mon action ajax s&rsquo;appelle : <strong><em>ccformationfilter</em></strong>, le même nom que la valeur de mon champs caché dans le formulaire de filtrage.</p>
<div class="code-embed-wrapper"> <pre class="language-markup code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-markup code-embed-code">&lt;input type=&quot;hidden&quot; name=&quot;action&quot; value=&quot;ccformationfilter&quot; /&gt;</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Je crée une première boucle pour mon bouton « all », sans distinction de catégorie:</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">$terms = get_terms( array( &#039;taxonomy&#039; =&gt; &#039;categories-formations&#039; ) );</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Juste en dessous, je crée une deuxième boucle qui me ramène les articles de la catégorie sélectionnée par l&rsquo;utilisateur</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">$args[&#039;tax_query&#039;] = array(<br/>			array(.....<br/><br/>&#039;terms&#039; =&gt; $_POST[&#039;category_formation_filters&#039;],</code></pre> <div class="code-embed-infos"> </div> </div>
<h3>Le fichier js</h3>
<p>Comme je l&rsquo;ai indiqué plus haut, on doit faire appel à un nouveau fichier js que j&rsquo;ai appelé <strong>load-more.js</strong></p>
<p>A l&rsquo;intérieur, on va créer nos deux fonctions, pour les filtres et le bouton<em> load more</em>.</p>
<div class="code-embed-wrapper"> <pre class="language-javascript code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-javascript code-embed-code">jQuery(function($){<br/><br/>/* LOAD MORE FUNCTION ON FORMATION ARCHIVE PAGE */<br/>$(&#039;#cc_formation_loadmore&#039;).click(function(){<br/>   data = {<br/>    &#039;action&#039;: &#039;loadmoreformationbutton&#039;, // le nom de mon action ajax<br/>    &#039;query&#039;: posts_myajax, // ma variable attribuée dans le fichier page-formation.php<br/>    &#039;page&#039; : current_page_myajax // ma variable attribuée dans le fichier page-formation.php<br/>  };<br/>  $.ajax({<br/>    url : &#039;/monsite/wp-admin/admin-ajax.php&#039;, // AJAX handler<br/>    data : data,<br/>    type : &#039;POST&#039;,<br/>    beforeSend : function ( xhr ) {<br/>      $(&#039;#cc_formation_loadmore&#039;).text(&#039;Recherche...&#039;); // ici l&#039;ID de mon bouton load more<br/>    },<br/>    success : function( posts ){<br/>      if( posts ) {<br/><br/>        $(&#039;#cc_formation_loadmore&#039;).text( &#039;Afficher plus de formations&#039; );<br/>        $(&#039;#cc_formation_wrap&#039;).append( posts ); <br/>       current_page_myajax++;<br/><br/>        if ( current_page_myajax == max_page_myajax )<br/>          $(&#039;#cc_formation_loadmore&#039;).hide(); <br/><br/>      } else {<br/>        $(&#039;#cc_formation_loadmore&#039;).hide(); <br/>      }<br/>    }<br/>  });<br/>  return false;<br/>});<br/><br/>/* FILTERING FUNCTION ON FORMATION ARCHIVE PAGE */<br/>$(&#039;#formation_filters&#039;).change(function(){<br/>  $.ajax({<br/>    url : &#039;/numgrade/wp-admin/admin-ajax.php&#039;,<br/>    data : $(&#039;#formation_filters&#039;).serialize(), // form data<br/>    dataType : &#039;json&#039;, <br/>    type : &#039;POST&#039;,<br/><br/>    success : function( data ){<br/><br/>      current_page_myajax = 1; <br/><br/>      posts_myajax = data.posts;<br/>     <br/>      max_page_myajax = data.max_page; <br/>      <br/>      $(&#039;#cc_formation_wrap&#039;).html(data.content); <br/>     <br/>      if ( data.max_page &lt; 2 ) {<br/>        $(&#039;#cc_formation_loadmore&#039;).hide();<br/>      } else {<br/>        $(&#039;#cc_formation_loadmore&#039;).show();<br/>      }<br/>    }<br/>  });<br/> <br/>  return false;<br/><br/>});<br/><br/>});</code></pre> <div class="code-embed-infos"> </div> </div>
<h3>La liaison entre tous ces fichiers</h3>
<p>Pour que le tout fonctionne, il faut surtout bien faire attention à nommer les éléments de la même manière d&rsquo;une page à l&rsquo;autre.</p>
<p>Les différents ID et nom attribués dans les autres fichiers se retrouvent dans le js:</p>
<p>L&rsquo;ID du conteneur principal : <strong><em>#cc_formation_wrap</em></strong></p>
<p>L&rsquo;ID de mon bouton load more : <strong>#cc_formation_loadmore</strong></p>
<p>Le nom de mon action ajax : <strong><em>loadmoreformationbutton</em></strong></p>
<p>L&rsquo;ID de mon formulaire de filtrage : <strong><em>#formation_filters</em></strong></p>
<p>mes variables crées dans le fichier page-formation.php  :<strong><em> current_page_myajax , posts_myajax et max_page_myajax.</em></strong></p>
<h3>Recommandations :</h3>
<p>Si malgré tout ce code vous ne parvenez pas à faire marcher le bouton loadmore en ajax ou le système de filtres, je vous invite à consulter les nombreux commentaires sur les pages suivantes :  <a href="https://rudrastyh.com/wordpress/load-more-posts-ajax.html">loadmore</a>, <a href="https://rudrastyh.com/wordpress/ajax-post-filters.html">filters</a>,  <a href="https://rudrastyh.com/wordpress/ajax-load-more-with-filters.html">ajax et filtres</a>, <a href="https://rudrastyh.com/wordpress/load-more-and-pagination.html">load more et pagination</a>. De nombreux internautes posent des questions et d&rsquo;autres y répondent. Vous devriez y trouver des pistes !</p>
<p>Si vous rencontrez un problème lors de l&rsquo;affichage des articles, notamment au niveau du nombre de posts affichés, changez le paramètre « posts_per_page » et modifiez également les options dans le backoffice de wordpress dans Réglages / Lecture.</p>
<p>The post <a rel="nofollow" href="https://www.copier-coller.com/filtrer-ses-custom-post-type-et-ajouter-un-bouton-load-more/">Filtrer ses custom post type et ajouter un bouton load more</a> appeared first on <a rel="nofollow" href="https://www.copier-coller.com">Copier coller</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.copier-coller.com/filtrer-ses-custom-post-type-et-ajouter-un-bouton-load-more/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Créer un système de notation (rating/reviews) sur wordpress sans pugin</title>
		<link>https://www.copier-coller.com/creer-un-systeme-de-notation-reviews-sur-wordpress/</link>
					<comments>https://www.copier-coller.com/creer-un-systeme-de-notation-reviews-sur-wordpress/#comments</comments>
		
		<dc:creator><![CDATA[copier coller]]></dc:creator>
		<pubDate>Mon, 20 Apr 2020 16:00:36 +0000</pubDate>
				<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://www.copier-coller.com/?p=6044</guid>

					<description><![CDATA[<p>Dans ce tuto, on va voir comment mettre en place un système de notation simple, sans faire appel à un plugin. La plupart des plugins de notation sont de vrais systèmes intégrés, avec la création à la volée de custom post types, la possibilité pour l&#8217;utilisateur de noter ou de commenter via un formulaire, etc. [...]</p>
<p>The post <a rel="nofollow" href="https://www.copier-coller.com/creer-un-systeme-de-notation-reviews-sur-wordpress/">Créer un système de notation (rating/reviews) sur wordpress sans pugin</a> appeared first on <a rel="nofollow" href="https://www.copier-coller.com">Copier coller</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Comment créer un système de notation interne sur wordpress ?</h2>
<p>Dans ce tuto, on va voir comment mettre en place un système de notation simple, sans faire appel à un plugin. La plupart des plugins de notation sont de vrais systèmes intégrés, avec la création à la volée de custom post types, la possibilité pour l&rsquo;utilisateur de noter ou de commenter via un formulaire, etc. Ce sont des solutions tout en un qui facilitent le travail des non développeurs, mais en réalité peu personnalisables.</p>
<p>Pour un besoin plus modeste, on va créer un système de notation propre, notamment grâce à la fonction <strong>wp_star_rating()</strong> intégrée d&rsquo;office dans wordpress !</p>
<h3>Ce dont on va avoir besoin :</h3>
<ul>
<li>un <strong>custom post type</strong> « avis » (cela marche aussi sur des articles bien sûr)</li>
<li><strong>ACF</strong> dans sa version gratuite, pour générer des<strong> metabox</strong> additionnelles pour nos différentes notes.</li>
<li>Le codex pour le code de base.</li>
</ul>
<h3>Le codex et la fonction wp_star_rating( $args )</h3>
<p>En fouillant un peu, on découvre en effet que wordpress dispose déjà d&rsquo;une fonction dédiée à la notation par étoiie, d&rsquo;où son nom : wp_star_rating !  <a href="https://developer.wordpress.org/reference/functions/wp_star_rating/">Le codex</a> explique brièvement comment l&rsquo;implémenter sur son site. On va donc voir comment s&rsquo;en servir.</p>
<h3>Prérequis :</h3>
<p>Selon le codex :   » <em>In order to use this function on the front end, your template must include the wp-admin/includes/template.php file and enqueue the appropriate dashicons CSS font information.</em> »</p>
<section class="source-content">
<div class="source-code-container">
<div></div>
</div>
</section>
<h3>L&rsquo;appel du fichier template.php</h3>
<p>On commence donc par appeler le fichier requis, avec ce bout de code à insérer dans le fichier <em><strong>functions.php</strong></em></p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">require_once( ABSPATH . &#039;wp-admin/includes/template.php&#039; );</code></pre> <div class="code-embed-infos"> </div> </div>
<h3>L&rsquo;utilisation de la fonction</h3>
<p>L&rsquo;exemple donné un peu partout est le suivant :</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">if ( !function_exists( &#039;wp_star_rating&#039; ) ) { <br/>    require_once ABSPATH . &#039;/wp-admin/includes/template.php&#039;; <br/>} <br/>  <br/>// Optional. Array of star ratings arguments. <br/>$args = array( <br/>    &#039;rating&#039; =&gt; 0, <br/>    &#039;type&#039; =&gt; &#039;rating&#039;, <br/>    &#039;number&#039; =&gt; 0 <br/>); <br/>  <br/>// NOTICE! Understand what this does before running. <br/>$result = wp_star_rating($args); </code></pre> <div class="code-embed-infos"> </div> </div>
<h3>Le style</h3>
<p>Toujours selon le codex, cette fonction fait appel à la police <a href="https://developer.wordpress.org/resource/dashicons/#format-aside">Dashicon</a>, et la doc recommande donc de l&rsquo;installer ou de faire appel à ces icônes. Voici en bonus, le style par défaut donné en exemple. Ici, on voit qu&rsquo;on a trois icônes, une étoile vide, une deuxième à moitié pleine, et une troisième entièrement colorée. Ces différentes icônes sont clairement nommées via les classes :</p>
<ul>
<li>star-full</li>
<li>star-half</li>
<li>star-empty</li>
</ul>
<p>Elles vont servir à indiquer la notation, puisque selon le codex, les chiffres sont « <em>expressed in either a 0.5 rating increment, or percentage.</em>« . Le 0.5 sera donc défini par l&rsquo;icone à moitié vide dont la classe est « star-half ».</p>
<div class="code-embed-wrapper"> <pre class="language-css code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-css code-embed-code">@font-face {<br/>    font-family: &quot;dashicons&quot;;<br/>    src: url(&quot;../fonts/dashicons.eot&quot;);<br/>}<br/> <br/>@font-face {<br/>    font-family: &quot;dashicons&quot;;<br/>    src: url(data:application/x-font-woff;charset=utf-8;base64,/* !! Large amount of data removed, see wp-includes/css/dashicons.css for complete data !! */) format(&quot;woff&quot;),<br/>        url(&quot;../fonts/dashicons.ttf&quot;) format(&quot;truetype&quot;),<br/>        url(&quot;../fonts/dashicons.svg#dashicons&quot;) format(&quot;svg&quot;);<br/>    font-weight: normal;<br/>    font-style: normal;<br/>}<br/> <br/>.star-rating .star-full:before {<br/>    content: &quot;\f155&quot;;<br/>}<br/> <br/>.star-rating .star-half:before {<br/>    content: &quot;\f459&quot;;<br/>}<br/> <br/>.star-rating .star-empty:before {<br/>    content: &quot;\f154&quot;;<br/>}<br/> <br/>.star-rating .star {<br/>    color: #0074A2;<br/>    display: inline-block;<br/>    font-family: dashicons;<br/>    font-size: 20px;<br/>    font-style: normal;<br/>    font-weight: 400;<br/>    height: 20px;<br/>    line-height: 1;<br/>    text-align: center;<br/>    text-decoration: inherit;<br/>    vertical-align: top;<br/>    width: 20px;<br/>}</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Voilà, maintenant qu&rsquo;on a les prérequis, on peut commencer !</p>
<h3>Un exemple concret d&rsquo;utilisation</h3>
<p>Pour notre exemple, on va partir d&rsquo;un besoin simple : dans notre site, l&rsquo;utilisateur final doit pouvoir manuellement ajouter des notes à ses articles ou custom post type.</p>
<p>Ces notes seront affichées de différentes manières en fonction de la page : une note sur des vignettes, des étoiles ou des ronds sur une page archive.</p>
<p>Voici le rendu souhaité : à travers un widget qui affiche des vignettes en slider. Ici on a un simple chiffre.</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6046" src="https://www.copier-coller.com/wp-content/uploads/2020/04/notation-wiget.png" alt="wp_star_rating( $args ) examples" width="1194" height="391" srcset="https://www.copier-coller.com/wp-content/uploads/2020/04/notation-wiget.png 1194w, https://www.copier-coller.com/wp-content/uploads/2020/04/notation-wiget-300x98.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/04/notation-wiget-1024x335.png 1024w, https://www.copier-coller.com/wp-content/uploads/2020/04/notation-wiget-768x251.png 768w, https://www.copier-coller.com/wp-content/uploads/2020/04/notation-wiget-624x204.png 624w" sizes="(max-width: 1194px) 100vw, 1194px" /></p>
<p>Et ici dans une page archive, avec des vignettes les unes à la suite des autres. Ici on a à la fois le même chiffre et en plus des icônes.</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6045" src="https://www.copier-coller.com/wp-content/uploads/2020/04/notation-archive.png" alt="wp_star_rating( $args ) examples" width="413" height="557" srcset="https://www.copier-coller.com/wp-content/uploads/2020/04/notation-archive.png 413w, https://www.copier-coller.com/wp-content/uploads/2020/04/notation-archive-222x300.png 222w" sizes="(max-width: 413px) 100vw, 413px" /></p>
<h3>Problématique</h3>
<p>Quand on est face à une demande similaire, on peut se demander comment on va faire pour avoir d&rsquo;un côté :</p>
<ul>
<li>une notation avec des chiffres</li>
<li>Une notation avec des chiffres, et en dessous des notes représentées par des icônes.</li>
</ul>
<p>L&rsquo;admin doit pouvoir insérer manuellement ces données, mais l&rsquo;idéal c&rsquo;est que la note chiffrée soit la moyenne, calculée automatiquement, des notes affichées par thème.</p>
<p>On va donc imaginer dans un custom post type  par exemple, un champ additionnel dans lequel l&rsquo;admin insérera une notation chiffrée, de 1 à 5.</p>
<p>Puis on va imaginer trois champs additionnels pour les thème « Animation » / « Contenu » / « Organisation ». L&rsquo;admin devra là aussi insérer manuellement une note, de 1 à 5.</p>
<p>Puisque la note chiffrée on la retrouve un peu partout sur le site, autant prévoir un champ automatisé, qui serait la moyenne des 3 autres notes insérées manuellement..</p>
<h3>Création d&rsquo;un custom post type</h3>
<p>Commençons d&rsquo;abord par créer notre custom post type « avis ». Celui ci dispose ici de deux taxonomies que je met ici, mais pour notre exemple, on en aura pas besoin.</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code"><br/>/*AVIS*/<br/>function cc_cpt_review() {<br/>	/* Formation */<br/>	$labels = array(<br/>		&#039;name&#039;                =&gt; _x(&#039;Avis&#039;, &#039;Post Type General Name&#039;, &#039;text_domain&#039;),<br/>		&#039;singular_name&#039;       =&gt; _x(&#039;Avis&#039;, &#039;Post Type Singular Name&#039;, &#039;text_domain&#039;),<br/>		&#039;menu_name&#039;           =&gt; _x(&#039;Avis&#039;, &#039;text_domain&#039;),<br/>		&#039;name_admin_bar&#039;      =&gt; _x(&#039;Avis&#039;, &#039;text_domain&#039;),<br/>		&#039;all_items&#039;           =&gt; _x(&#039;Tous les Avis&#039;, &#039;text_domain&#039;),<br/>		&#039;add_new_item&#039;        =&gt; _x(&#039;Ajouter un nouvel Avis&#039;, &#039;text_domain&#039;),<br/>		&#039;add_new&#039;             =&gt; _x(&#039;Ajouter&#039;, &#039;text_domain&#039;),<br/>		&#039;new_item&#039;            =&gt; _x(&#039;Nouvel avis&#039;, &#039;text_domain&#039; ),<br/>		&#039;edit_item&#039;           =&gt; _x(&#039;Editer l\&#039;avis&#039;, &#039;text_domain&#039;),<br/>		&#039;update_item&#039;         =&gt; _x(&#039;Mettre à jour l\&#039;avis&#039;, &#039;text_domain&#039;),<br/>		&#039;view_item&#039;           =&gt; _x(&#039;Voir l\&#039;avis&#039;, &#039;text_domain&#039;),<br/>		&#039;search_items&#039;        =&gt; _x(&#039;Rechercher un avis&#039;, &#039;text_domain&#039;),<br/>		&#039;not_found&#039;           =&gt; _x(&#039;Aucun avis trouvé&#039;, &#039;text_domain&#039;),<br/>		&#039;not_found_in_trash&#039;  =&gt; _x(&#039;Aucun avis trouvé dans la corbeille&#039;, &#039;text_domain&#039;),<br/>	);<br/>	<br/>	$args = array(<br/>		&#039;label&#039;               =&gt; _x(&#039;Avis&#039;, &#039;text_domain&#039;),<br/>		&#039;description&#039;         =&gt; _x(&#039;Avis&#039;, &#039;text_domain&#039;),<br/>		&#039;labels&#039;              =&gt; $labels,<br/>		&#039;supports&#039;            =&gt; array(&#039;title&#039;, &#039;editor&#039;, &#039;thumbnail&#039;, &#039;comments&#039;, &#039;revisions&#039;, &#039;custom-fields&#039;),<br/>		&#039;hierarchical&#039;        =&gt; false,<br/>		&#039;public&#039;              =&gt; true,<br/>		&#039;show_ui&#039;             =&gt; true,<br/>		&#039;show_in_menu&#039;        =&gt; true,<br/>		&#039;menu_position&#039;       =&gt; 5,<br/>		&#039;menu_icon&#039;           =&gt; &#039;dashicons-admin-home&#039;,<br/>		&#039;show_in_admin_bar&#039;   =&gt; true,<br/>		&#039;show_in_nav_menus&#039;   =&gt; true,<br/>		&#039;can_export&#039;          =&gt; true,<br/>		&#039;has_archive&#039;         =&gt; false,<br/>		&#039;exclude_from_search&#039; =&gt; false,<br/>		&#039;publicly_queryable&#039;  =&gt; true,<br/>		&#039;query_var&#039;           =&gt; &#039;avis&#039;,<br/>		&#039;rewrite&#039;             =&gt;  array( &#039;slug&#039; =&gt; &#039;tous-les-avis&#039; ),<br/>		&#039;capability_type&#039;     =&gt; &#039;post&#039;,<br/>		&#039;show_in_rest&#039;			=&gt;&#039;true&#039;,<br/>	);<br/>	register_post_type(&#039;avis&#039;, $args);	<br/>}<br/>add_action(&#039;init&#039;, &#039;cc_cpt_review&#039;, 10);<br/><br/><br/><br/>function cc_add_taxonomies_review() {<br/>	// Catégorie de série<br/>	$labels_cat_avis = array(<br/>		&#039;name&#039;                       =&gt; _x( &#039;Catégories de l\&#039;avis&#039;, &#039;taxonomy general name&#039;),<br/>		&#039;singular_name&#039;              =&gt; _x( &#039;Catégories de l\&#039;avis&#039;, &#039;taxonomy singular name&#039;),<br/>		&#039;search_items&#039;               =&gt; __( &#039;Rechercher une catégorie&#039;),<br/>		&#039;popular_items&#039;              =&gt; __( &#039;Catégories populaires&#039;),<br/>		&#039;all_items&#039;                  =&gt; __( &#039;Toutes les catégories&#039;),<br/>		&#039;edit_item&#039;                  =&gt; __( &#039;Editer une catégorie&#039;),<br/>		&#039;update_item&#039;                =&gt; __( &#039;Mettre à jour une catégorie&#039;),<br/>		&#039;add_new_item&#039;               =&gt; __( &#039;Ajouter une nouvelle catégorie&#039;),<br/>		&#039;new_item_name&#039;              =&gt; __( &#039;Nom de la nouvelle catégorie&#039;),<br/>		&#039;add_or_remove_items&#039;        =&gt; __( &#039;Ajouter ou supprimer une catégorie&#039;),<br/>		&#039;choose_from_most_used&#039;      =&gt; __( &#039;Choisir parmi les catégories les plus utilisées&#039;),<br/>		&#039;not_found&#039;                  =&gt; __( &#039;Pas de catégories trouvée&#039;),<br/>		&#039;menu_name&#039;                  =&gt; __( &#039;Catégorie d\&#039;avis&#039;),<br/>	);<br/><br/>	$args_cat_avis = array(<br/><br/>		&#039;hierarchical&#039;          =&gt; true,<br/>		&#039;labels&#039;                =&gt; $labels_cat_avis,<br/>		&#039;show_ui&#039;               =&gt; true,<br/>		&#039;show_in_rest&#039;			=&gt; true,<br/>		&#039;show_admin_column&#039;     =&gt; true,<br/>		&#039;query_var&#039;             =&gt; true,<br/>		&#039;rewrite&#039;               =&gt; array( &#039;slug&#039; =&gt; &#039;categories-avis&#039; ),<br/>	);<br/><br/>	register_taxonomy( &#039;categories-avis&#039;, &#039;avis&#039;, $args_cat_avis );<br/>}<br/>add_action( &#039;init&#039;, &#039;cc_add_taxonomies_review&#039;, 0 );<br/><br/>function cc_avis_level_taxonomies() {<br/><br/>	$labels_level_avis = array(<br/>		&#039;name&#039;                       =&gt; _x( &#039;Niveaux de l\&#039;avis&#039;, &#039;taxonomy general name&#039;),<br/>		&#039;singular_name&#039;              =&gt; _x( &#039;Niveau de l\&#039;avis&#039;, &#039;taxonomy singular name&#039;),<br/>		&#039;search_items&#039;               =&gt; __( &#039;Rechercher un avis&#039;),<br/>		&#039;popular_items&#039;              =&gt; __( &#039;Niveaux populaires&#039;),<br/>		&#039;all_items&#039;                  =&gt; __( &#039;Tous les Niveaux&#039;),<br/>		&#039;edit_item&#039;                  =&gt; __( &#039;Editer un niveau&#039;),<br/>		&#039;update_item&#039;                =&gt; __( &#039;Mettre à jour un niveau&#039;),<br/>		&#039;add_new_item&#039;               =&gt; __( &#039;Ajouter un nouveau niveau&#039;),<br/>		&#039;new_item_name&#039;              =&gt; __( &#039;Nom de le nouveau niveau&#039;),<br/>		&#039;add_or_remove_items&#039;        =&gt; __( &#039;Ajouter ou supprimer un niveau&#039;),<br/>		&#039;choose_from_most_used&#039;      =&gt; __( &#039;Choisir parmi les niveaux les plus utilisés&#039;),<br/>		&#039;not_found&#039;                  =&gt; __( &#039;Pas de niveau trouvé&#039;),<br/>		&#039;menu_name&#039;                  =&gt; __( &#039;Niveau de l\&#039;avis&#039;),<br/>	);<br/><br/>	$args_level_avis = array(<br/>	<br/>		&#039;hierarchical&#039;          =&gt; true,<br/>		&#039;labels&#039;                =&gt; $labels_level_avis,<br/>		&#039;show_ui&#039;               =&gt; true,<br/>		&#039;show_in_rest&#039;			=&gt; true,<br/>		&#039;show_admin_column&#039;     =&gt; true,<br/>		&#039;query_var&#039;             =&gt; true,<br/>		&#039;rewrite&#039;               =&gt; array( &#039;slug&#039; =&gt; &#039;niveau-avis&#039; ),<br/>	);<br/><br/>	register_taxonomy( &#039;niveau-avis&#039;, &#039;avis&#039;, $args_level_avis );<br/>}<br/>add_action( &#039;init&#039;, &#039;cc_avis_level_taxonomies&#039;, 0 );</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Une fois crée, on retrouve notre CPT (custom post type) donc dans le backoffice du site, et on peut commencer à remplir des « avis », comme on le ferait pour un article.</p>
<p>Mais avant cela, on va créer des champs additionnels pour nos « avis » grâce à ACF.</p>
<h3>Création de meta box ACF</h3>
<p>On va donc créer un <strong>groupe de champs</strong> propre à nos « avis ». A l&rsquo;intérieur, le premier champ à créer sera la « note » globale. On choisit comme <em><strong>type de champ</strong></em> : « <strong><em>Nombre</em></strong>« .</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6049" src="https://www.copier-coller.com/wp-content/uploads/2020/04/acf-note.png" alt="acf number field" width="1404" height="285" srcset="https://www.copier-coller.com/wp-content/uploads/2020/04/acf-note.png 1404w, https://www.copier-coller.com/wp-content/uploads/2020/04/acf-note-300x61.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/04/acf-note-1024x208.png 1024w, https://www.copier-coller.com/wp-content/uploads/2020/04/acf-note-768x156.png 768w, https://www.copier-coller.com/wp-content/uploads/2020/04/acf-note-624x127.png 624w" sizes="(max-width: 1404px) 100vw, 1404px" /></p>
<p>On va ensuite créer nos trois autres notes »Animation », « Contenu » et « Organisation ».</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6047" src="https://www.copier-coller.com/wp-content/uploads/2020/04/acf-fields.png" alt="acf number field" width="1443" height="228" srcset="https://www.copier-coller.com/wp-content/uploads/2020/04/acf-fields.png 1443w, https://www.copier-coller.com/wp-content/uploads/2020/04/acf-fields-300x47.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/04/acf-fields-1024x162.png 1024w, https://www.copier-coller.com/wp-content/uploads/2020/04/acf-fields-768x121.png 768w, https://www.copier-coller.com/wp-content/uploads/2020/04/acf-fields-624x99.png 624w" sizes="(max-width: 1443px) 100vw, 1443px" /></p>
<p>Ce sont également des champs de type « <strong><em>nombre</em></strong>« , sauf que cette fois on précise une valeur minimale de 1 et une note maximale de 5.</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6048" src="https://www.copier-coller.com/wp-content/uploads/2020/04/acf-min-max.png" alt="acf number field" width="1404" height="125" srcset="https://www.copier-coller.com/wp-content/uploads/2020/04/acf-min-max.png 1404w, https://www.copier-coller.com/wp-content/uploads/2020/04/acf-min-max-300x27.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/04/acf-min-max-1024x91.png 1024w, https://www.copier-coller.com/wp-content/uploads/2020/04/acf-min-max-768x68.png 768w, https://www.copier-coller.com/wp-content/uploads/2020/04/acf-min-max-624x56.png 624w" sizes="(max-width: 1404px) 100vw, 1404px" /></p>
<p>Pour finir, on n&rsquo;oublie pas de préciser que le groupe de champs ne devra apparaître que dans le « <strong><em>type de publication</em></strong> » &#8211; « Avis »</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6050" src="https://www.copier-coller.com/wp-content/uploads/2020/04/acf-type.png" alt="acf number field" width="1438" height="203" srcset="https://www.copier-coller.com/wp-content/uploads/2020/04/acf-type.png 1438w, https://www.copier-coller.com/wp-content/uploads/2020/04/acf-type-300x42.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/04/acf-type-1024x145.png 1024w, https://www.copier-coller.com/wp-content/uploads/2020/04/acf-type-768x108.png 768w, https://www.copier-coller.com/wp-content/uploads/2020/04/acf-type-624x88.png 624w" sizes="(max-width: 1438px) 100vw, 1438px" /></p>
<p>Pour le type de publication, on peut faire un peu ce qu&rsquo;on veut, ça dépend vraiment de votre projet de base.</p>
<h3>Dans la page d&rsquo;édition de mon custom post type</h3>
<p>Dans la page d&rsquo;édition d&rsquo;un « avis », on retrouve les différents champs ACF.  On peut donc renseigner manuellement une note, en tapant directement un chiffre ou en s&rsquo;aidant des flèches de navigation qui apparaissent au survol du champ. Petite précision, si vous tapez un chiffre le champ l&rsquo;acceptera, quelqu&rsquo;il soit, alors que si on utilise les flèches, on est bien limité de 1 à 5.</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6052" src="https://www.copier-coller.com/wp-content/uploads/2020/04/post-edit-acf-fields.png" alt="post edit acf fields" width="1445" height="259" srcset="https://www.copier-coller.com/wp-content/uploads/2020/04/post-edit-acf-fields.png 1445w, https://www.copier-coller.com/wp-content/uploads/2020/04/post-edit-acf-fields-300x54.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/04/post-edit-acf-fields-1024x184.png 1024w, https://www.copier-coller.com/wp-content/uploads/2020/04/post-edit-acf-fields-768x138.png 768w, https://www.copier-coller.com/wp-content/uploads/2020/04/post-edit-acf-fields-624x112.png 624w" sizes="(max-width: 1445px) 100vw, 1445px" /></p>
<p>Attention : pour l&rsquo;instant il ne faut rien indiquer dans le champs « note », celui-ci est censé se remplir tout seul, grâce à une fonction qui fera la moyenne des trois autres notes.</p>
<h3>Créer le système de notation</h3>
<p>Dans le fichier pnp de son CPT, on va maintenant appeler nos différents champs ACF, afin d&rsquo;afficher nos notes.</p>
<p>Tout d&rsquo;abord, j&rsquo;appelle le champ « note » qui va contenir ma note globale. C&rsquo;est le gros 4.5/5, 2.7/5 que vous voyez sur les images plus haut. Pour l&rsquo;instant il ne doit rien afficher, puisqu&rsquo;on n&rsquo;a pas encore rempli ce champ.</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;div class=&quot;review-score&quot;&gt;<br/>								&lt;?php	 	<br/>									$note = get_field(&#039;note&#039;);<br/>									if($note): <br/>									 $args = array(<br/>									   &#039;rating&#039; =&gt; $note,<br/>									   &#039;type&#039; =&gt; &#039;rating&#039;,<br/>									   &#039;number&#039; =&gt; &#039;&#039;,<br/>									);?&gt;<br/>									&lt;div&gt;<br/>										&lt;span class=&quot;note&quot;&gt;&lt;?php echo round($note,1) ?&gt;/5&lt;/span&gt;&lt;span class=&quot;average&quot;&gt;&lt;?php wp_star_rating( $args ) ?&gt;&lt;/span&gt;&lt;/div&gt;<br/>									&lt;?php endif;?&gt;<br/>									&lt;/div&gt;</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Ici je ramène la valeur de mon champs avec le <strong><em>get_field (&lsquo;note&rsquo;);</em></strong> Je la mets dans une variable et la passe comme argument de ma fonction <em><strong>wp_star_rating();</strong></em></p>
<p>D&rsquo;un côté je veux afficher la valeur du champs, donc une note :</p>
<div class="code-embed-wrapper"> <pre class="language-markup code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-markup code-embed-code">&lt;span class=&quot;note&quot;&gt;&lt;?php echo round($note,1) ?&gt;/5&lt;/span&gt;</code></pre> <div class="code-embed-infos"> </div> </div>
<p>J&rsquo;utilise la fonction <strong><em>round()</em></strong>, avec le 1 pour arrondir à une décimale après la virgule.</p>
<p>De l&rsquo;autre côté, ou juste à côté plutôt je veux afficher le même résultat mais en icône. J&rsquo;affiche donc directement la fonction avec mes arguments, wordpress s&rsquo;occupe du reste. Si ma note est 4.5/5 par exemple, il va appeler 4 icones pleine, puis une à moitié vide.</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;span class=&quot;average&quot;&gt;&lt;?php wp_star_rating( $args ) ?&gt;&lt;/span&gt;</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Ce bout de code sera à terme censé m&rsquo;afficher ca :</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6054" src="https://www.copier-coller.com/wp-content/uploads/2020/04/note-globale-acf.png" alt="3 champs acf" width="239" height="57" /></p>
<p>Ensuite, pour afficher les notes du dessous j&rsquo;appelle de la même manière les valeurs de mes autres champs:</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">		&lt;?php if (get_field(&#039;animation&#039;) || get_field(&#039;contenu&#039;)  || get_field(&#039;organisation&#039;) ): ?&gt;<br/>		<br/>						&lt;div class=&quot;review-score_features&quot;&gt;<br/>							&lt;div class=&quot;review-score_features_left&quot;&gt;<br/>								&lt;?php			<br/>									if(get_field(&#039;animation&#039;))<br/>									{ 	$animation = get_field_object(&#039;animation&#039;);<br/>										echo &#039;&lt;div class=&quot;review-score_features_left_bloc&quot;&gt;&#039; . $animation[&#039;label&#039;] .&#039;&lt;/div&gt;&#039;;<br/>									}<br/><br/>									if(get_field(&#039;contenu&#039;))<br/>									{ 	$contenu = get_field_object(&#039;contenu&#039;);<br/>										echo &#039;&lt;div class=&quot;review-score_features_left_bloc&quot;&gt;&#039; . $contenu[&#039;label&#039;] .&#039;&lt;/div&gt;&#039;;<br/>									}<br/>									if(get_field(&#039;organisation&#039;))<br/>									{ 	$organisation = get_field_object(&#039;organisation&#039;);<br/>										echo &#039;&lt;div class=&quot;review-score_features_left_bloc&quot;&gt;&#039; . $organisation[&#039;label&#039;] .&#039;&lt;/div&gt;&#039;;<br/>									}<br/>								?&gt;<br/>							&lt;/div&gt;<br/>							&lt;div class=&quot;review-score_features_right&quot;&gt;<br/>							&lt;?php<br/><br/>								$animation = get_field(&#039;animation&#039;);<br/>								if($animation):<br/>								 $args = array(<br/>								   &#039;rating&#039; =&gt; $animation,<br/>								   &#039;type&#039; =&gt; &#039;rating&#039;,<br/>								   &#039;number&#039; =&gt; &#039;&#039;,<br/>								);?&gt;<br/>								<br/>								&lt;div class=&quot;review-score_features_right_bloc&quot;&gt;&lt;?php  wp_star_rating( $args )?&gt;&lt;/div&gt;<br/>								&lt;?php endif;?&gt;<br/><br/>								&lt;?php <br/>								$contenu = get_field(&#039;contenu&#039;);<br/>								if($contenu):<br/>								 $args = array(<br/>								   &#039;rating&#039; =&gt; $contenu,<br/>								   &#039;type&#039; =&gt; &#039;rating&#039;,<br/>								   &#039;number&#039; =&gt; &#039;&#039;,<br/>								);?&gt;<br/>								<br/>								&lt;div class=&quot;review-score_features_right_bloc&quot;&gt;&lt;?php  wp_star_rating( $args )?&gt;&lt;/div&gt;<br/>								&lt;?php endif;?&gt;<br/><br/>								&lt;?php <br/>								$organisation = get_field(&#039;organisation&#039;);<br/>								 if($organisation):<br/>								 $args = array(<br/>								   &#039;rating&#039; =&gt; $organisation,<br/>								   &#039;type&#039; =&gt; &#039;rating&#039;,<br/>								   &#039;number&#039; =&gt; &#039;&#039;,<br/>								);?&gt;<br/>								<br/>								&lt;div class=&quot;review-score_features_right_bloc&quot;&gt;&lt;?php  wp_star_rating( $args )?&gt;&lt;/div&gt;<br/>								&lt;?php endif;?&gt;<br/>							&lt;/div&gt;<br/>							&lt;/div&gt;<br/>						&lt;?php endif;?&gt;</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Un <strong><em>get_field()</em></strong> à chaque fois pour récupérer la valeur, et je passe la variable dans les arguments de ma fonction.</p>
<p>Cela est censé m&rsquo;afficher des icônes comme ci-dessous.</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6053" src="https://www.copier-coller.com/wp-content/uploads/2020/04/3-champs-acf.png" alt="3 champs acf" width="315" height="114" srcset="https://www.copier-coller.com/wp-content/uploads/2020/04/3-champs-acf.png 315w, https://www.copier-coller.com/wp-content/uploads/2020/04/3-champs-acf-300x109.png 300w" sizes="(max-width: 315px) 100vw, 315px" /></p>
<p>Si vous utilisez <em><strong>dashicons</strong> </em>et les icônes d&rsquo;étoiles par défaut fourni dans le code css plus haut, vous aurez ici des étoiles à la place des ronds. On va voir plus bas comment mettre ses propres icônes.</p>
<p>Ici, comme le texte utilisé correspond aux titres de mes champs ACF, je peux directement utiliser la fonction <strong><em>get_field_object</em></strong> pour récupérer l&rsquo;ensemble des attributs de mon champ, et en extraire le titre ou « <em>label</em>« . Ce sont les titres « Animation », « Contenu » et « Organisation » que vous voyez plus haut.</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">if(get_field(&#039;animation&#039;))<br/>									{ 	$animation = get_field_object(&#039;animation&#039;);<br/>										echo &#039;&lt;div class=&quot;review-score_features_left_bloc&quot;&gt;&#039; . $animation[&#039;label&#039;] .&#039;&lt;/div&gt;&#039;;<br/>									}</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Dans un widget d&rsquo;avis, sur lesquels ne figure que la note globale, j&rsquo;utilise exactement le même code</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;div class=&quot;review-score&quot;&gt;<br/>								&lt;?php $note = get_field(&#039;note&#039;);<br/>									 if($note){ 	<br/>									<br/>									echo &#039;&lt;div&gt;&lt;span class=&quot; note&quot;&gt;&#039; . round($note,1) . &#039;/5&lt;/span&gt;&lt;/div&gt;&#039;;<br/>									}<br/>								?&gt;<br/>							&lt;/div&gt;</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Ici il n&rsquo;y a pas d&rsquo;étoile ou d&rsquo;icône, juste la valeur de mon champ « note ».</p>
<h3>La fonction de calcul</h3>
<p>Maintenant on va voir comment on peut faire en sorte que le champs ACF « note » soit calculé automatiquement.</p>
<p>Pour cela on va devoir insérer une fonction de calcul à l&rsquo;intérieur du hook ACF &lsquo;<strong><em>acf/save_post</em></strong>&lsquo;.</p>
<p>Voici la fonction, à placer dans le fichier <strong><em>functions.php</em></strong></p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">function my_acf_save_post( $post_id ) {<br/>    <br/>// get new value<br/>$animation = get_field(&#039;animation&#039;);<br/>$contenu = get_field(&#039;contenu&#039;);<br/>$organisation = get_field(&#039;organisation&#039;);<br/>    <br/>// do something<br/>$note_globale = $animation + $contenu + $organisation;<br/>$note_finale = $note_globale / 3;<br/>$note = number_format($note_finale,1);<br/>update_field(&#039;note&#039;, $note, $post_id);	<br/>}<br/>add_action(&#039;acf/save_post&#039;, &#039;my_acf_save_post&#039;, 20);</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Comme vous pouvez le voir, c&rsquo;est assez simple. On récupère la valeur de nos trois champs ACF « Animation », « Contenu » et « Organisation ».</p>
<p>On les additionne et on met la somme dans une variable. Puisque ca doit faire la moyenne de trois note, on divise par trois. On met le résultat dans une nouvelle variable. Cette variable, on la passe dans la fonction <em>number_format</em></p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">number_format($note_finale,1);</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Le 1 sert à limiter à une, le nombre de décimale après la virgule. Pourquoi <em>number_format</em> et pas <em>round()</em> ? Ne me demandez pas, ici <strong><em>round()</em></strong> ne marche tout simplement pas !</p>
<p>Enfin, on utilise la fonction <strong><em>update_field()</em></strong>; pour mettre à jour le champ « note » laissé vide jusque là.</p>
<p>Maintenant une fois que vous aurez rempli les trois champs, Vous pourrez enregistrez votre page à l&rsquo;édition, rechargez en faisant un <em>Ctrl F5</em>, et le champ affichera la moyenne directement !</p>
<h3>Le style personnalisé</h3>
<p>Personnellement, dans ce projet, je n&rsquo;ai pas appelé la bibliothèque dashicons. Puisque je dois afficher des ronds et non des étoiles, je vais devoir trouver une solution personnalisée.</p>
<p>En fait j&rsquo;utilise les même classes que celles utilisées ou générées par la fonction <strong>wp_star_rating( $args )</strong> et j&rsquo;appelle simplement en background mes images perso.  Les images, soit on les crée soit-même, soit on utilise des images récupérées sur le net, sur <a href="https://www.flaticon.com/">flaticon</a> ou tout autre site d&rsquo;icône.</p>
<div class="code-embed-wrapper"> <pre class="language-css code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-css code-embed-code">.star-rating{<br/>	display:inline-block;<br/>}<br/>.star-rating .star-full:before {<br/>    content: &quot;&quot;;<br/>    background: url(img/full.png);<br/>    display: inline-block;<br/>    position: relative;<br/>    background-size: 10px;<br/>    background-repeat: no-repeat;<br/>    width: 10px;<br/>    height: 10px;<br/>    margin: 0 5px;<br/>}<br/>.star-rating .star-half:before {<br/>    content: &quot;&quot;;<br/>    background: url(img/mid-full.png);<br/>    display: inline-block;<br/>    position: relative;<br/>    background-size: 10px;<br/>    background-repeat: no-repeat;<br/>    width: 10px;<br/>    height: 10px;<br/>    margin: 0 5px;<br/>}<br/>.star-rating .star-empty:before {<br/>    content: &quot;&quot;;<br/>    background: url(img/empty.png);<br/>    display: inline-block;<br/>    position: relative;<br/>    background-repeat: no-repeat;<br/>    background-size: 10px;<br/>    width: 10px;<br/>    height: 10px;<br/>    margin: 0 5px;<br/>}<br/>.star-rating .star {<br/>    display: inline-block;<br/>    vertical-align: top;<br/>}</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Voilà donc comment intégrer assez simplement un système de notation, plutôt statique, mais qui peut faire son effet !</p>
<p>N&rsquo;hésitez pas, si vous avez des idées d&rsquo;amélioration ou des corrections à apporter à ce tuto !</p>
<p>The post <a rel="nofollow" href="https://www.copier-coller.com/creer-un-systeme-de-notation-reviews-sur-wordpress/">Créer un système de notation (rating/reviews) sur wordpress sans pugin</a> appeared first on <a rel="nofollow" href="https://www.copier-coller.com">Copier coller</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.copier-coller.com/creer-un-systeme-de-notation-reviews-sur-wordpress/feed/</wfw:commentRss>
			<slash:comments>11</slash:comments>
		
		
			</item>
		<item>
		<title>Affichage alterné pour site multilingue</title>
		<link>https://www.copier-coller.com/affichage-alterne-pour-site-multilingue/</link>
					<comments>https://www.copier-coller.com/affichage-alterne-pour-site-multilingue/#respond</comments>
		
		<dc:creator><![CDATA[copier coller]]></dc:creator>
		<pubDate>Sat, 18 Apr 2020 18:35:37 +0000</pubDate>
				<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://www.copier-coller.com/?p=6124</guid>

					<description><![CDATA[<p>Tout dépend du contexte, mais dans certains cas, et pour certains thèmes wordpress, il se peut qu&#8217;on ait besoin d&#8217;afficher un certain contenu en français, et un autre en anglais par exemple : Si vous utilisez WMPL : Si vous utilisez Polylang: Chaque plugin a ses petites nuances de syntaxe, mais la logique est la [...]</p>
<p>The post <a rel="nofollow" href="https://www.copier-coller.com/affichage-alterne-pour-site-multilingue/">Affichage alterné pour site multilingue</a> appeared first on <a rel="nofollow" href="https://www.copier-coller.com">Copier coller</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Comment afficher différents contenus en fonction de la langue?</h2>
<p>Tout dépend du contexte, mais dans certains cas, et pour certains thèmes wordpress, il se peut qu&rsquo;on ait besoin d&rsquo;afficher un certain contenu en français, et un autre en anglais par exemple :</p>
<p>Si vous utilisez WMPL :</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;?php if (ICL_LANGUAGE_CODE == &quot;fr&quot;) { ?&gt;<br/>    Votre contenu hmlt fr<br/>&lt;?php } elseif (ICL_LANGUAGE_CODE == &quot;en&quot;) { ?&gt;<br/> 	votre contenu html en<br/>&lt;?php  } ?&gt;</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Si vous utilisez Polylang:</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code"> &lt;?php<br/> 				$currentlang = get_bloginfo(&#039;language&#039;);<br/>    			if($currentlang==&quot;fr-FR&quot;): ?&gt;<br/>		<br/>				votre conteneu fr<br/>				&lt;?php <br/>    			// si la langue affichee est l&#039;anglais US<br/>    			elseif($currentlang==&quot;en-GB&quot;):?&gt;<br/><br/>				votre conteneu en<br/>				&lt;?php endif; ?&gt;	</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Chaque plugin a ses petites nuances de syntaxe, mais la logique est la même derrière !</p>
<p>The post <a rel="nofollow" href="https://www.copier-coller.com/affichage-alterne-pour-site-multilingue/">Affichage alterné pour site multilingue</a> appeared first on <a rel="nofollow" href="https://www.copier-coller.com">Copier coller</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.copier-coller.com/affichage-alterne-pour-site-multilingue/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Filtrer ses articles et ajouter un bouton « loadmore »</title>
		<link>https://www.copier-coller.com/filtrer-ses-articles-et-ajouter-un-bouton-loadmore/</link>
					<comments>https://www.copier-coller.com/filtrer-ses-articles-et-ajouter-un-bouton-loadmore/#comments</comments>
		
		<dc:creator><![CDATA[copier coller]]></dc:creator>
		<pubDate>Sat, 18 Apr 2020 18:22:55 +0000</pubDate>
				<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://www.copier-coller.com/?p=6075</guid>

					<description><![CDATA[<p>Aujourd&#8217;hui on va voir comment créer un système de filtre (classification) pour les articles, et ajouter une navigation ajax grâce à un bouton load more. Le code s&#8217;inspire très largement de l’excellent tuto de rudrastyh, sauf que nous on ne va pas utiliser le même système de filtres. Dans son tutoriel, rudrastyh utilise des champs [...]</p>
<p>The post <a rel="nofollow" href="https://www.copier-coller.com/filtrer-ses-articles-et-ajouter-un-bouton-loadmore/">Filtrer ses articles et ajouter un bouton « loadmore »</a> appeared first on <a rel="nofollow" href="https://www.copier-coller.com">Copier coller</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Comment créer un filtre et un bouton ajax load more pour vos articles ?</h2>
<p>Aujourd&rsquo;hui on va voir comment créer un système de filtre (classification) pour les articles, et ajouter une navigation ajax grâce à un bouton load more.</p>
<h3>Les sources</h3>
<p>Le code s&rsquo;inspire très largement de l’excellent tuto de <a href="https://rudrastyh.com/wordpress/ajax-load-more-with-filters.html">rudrastyh</a>, sauf que nous on ne va pas utiliser le même système de filtres. Dans son tutoriel, rudrastyh utilise des champs select qu&rsquo;il relie entre eux. Dans notre exemple, on va partir sur des checkbox ou boutons radios, stylisés en bouton. Pour une simple liste en ul&gt;li, le code sera le même.</p>
<p>Je me suis également appuyé sur le tuto d&rsquo;<a href="https://www.aliciaramirez.com/2014/03/integrating-isotope-with-wordpress/">Alicia ramirez</a>, qui en fait une utilisation plus simple en utilisant isotope.js.</p>
<p>On va partir ici d&rsquo;un cadre relativement simple, celui des articles classiques de wordpress.</p>
<h3>Un affichage original</h3>
<p>On va en plus permettre un affichage original de nos articles, avec un système en colonnes, qui se reproduira à chaque filtrage .</p>
<p>Voici donc le résultat auquel on veut parvenir :</p>
<p><img decoding="async" loading="lazy" class="alignnone wp-image-6076 size-large" src="https://www.copier-coller.com/wp-content/uploads/2020/04/filtres-ajax-wordpress-669x1024.png" alt="filtres ajax wordpress" width="625" height="957" srcset="https://www.copier-coller.com/wp-content/uploads/2020/04/filtres-ajax-wordpress-669x1024.png 669w, https://www.copier-coller.com/wp-content/uploads/2020/04/filtres-ajax-wordpress-196x300.png 196w, https://www.copier-coller.com/wp-content/uploads/2020/04/filtres-ajax-wordpress-768x1176.png 768w, https://www.copier-coller.com/wp-content/uploads/2020/04/filtres-ajax-wordpress-1003x1536.png 1003w, https://www.copier-coller.com/wp-content/uploads/2020/04/filtres-ajax-wordpress-1337x2048.png 1337w, https://www.copier-coller.com/wp-content/uploads/2020/04/filtres-ajax-wordpress-624x956.png 624w, https://www.copier-coller.com/wp-content/uploads/2020/04/filtres-ajax-wordpress.png 1371w" sizes="(max-width: 625px) 100vw, 625px" /></p>
<p>L&rsquo;originalité de mon exemple, c&rsquo;est qu&rsquo;au clic sur n&rsquo;importe lequel des filtres, la présentation des vignettes d&rsquo;articles sera la même, avec toujours en premier, une vignette de 12 colonnes, ensuite 6, puis 4.</p>
<h3>Ce dont on va avoir besoin :</h3>
<ul>
<li>Des articles. Cela paraît évident, donc il faut créer des articles pour que le système fonctionne.</li>
<li>Des catégories : liez vos articles à des catégories, les boutons des filtres représentent justement vos catégories.</li>
<li>Une grille en colonne, j&rsquo;utilise ici une grille flexbox originale que vous pouvez trouver <a href="https://www.copier-coller.com/flex-un-exemple-de-grille/">ici.</a></li>
</ul>
<h3>La structure de base</h3>
<p>Je repars ici de <a href="https://www.copier-coller.com/creer-des-blocs-de-differentes-tailles-dans-vos-pages-darchives/">mon exemple précédent</a>, auquel je rajoute le système de filtres. Je suis dans ma page blog, donc dans mon fichier <em><strong>index.php</strong></em> ou <em><strong>home.php.</strong></em></p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;div class=&quot;flex-container&quot;&gt;<br/>	&lt;div class=&quot;flex-row&quot;&gt;	<br/>		&lt;header class=&quot;page-header&quot;&gt;<br/>			&lt;?php<br/>			single_post_title(&#039;&lt;h1 class=&quot;page-title&quot;&gt;&#039;, &#039;&lt;/h1&gt;&#039; );<br/>			?&gt;<br/>		&lt;/header&gt;&lt;!-- .page-header --&gt;<br/>	&lt;/div&gt;<br/>	&lt;div class=&quot;flex-row&quot;&gt;<br/>		&lt;form action=&quot;#&quot; method=&quot;POST&quot; id=&quot;post_filters&quot;&gt;<br/>			&lt;p&gt;&lt;input type=&quot;radio&quot; value=&quot;all&quot; id=&quot;all&quot; class=&quot;category_filter&quot; name=&quot;category_filters&quot;&gt;&lt;label for=&quot;all&quot;&gt;Toutes&lt;/label&gt;&lt;/p&gt;<br/>			&lt;?php <br/>			if( $terms = get_terms( array( &#039;taxonomy&#039; =&gt; &#039;category&#039; ) ) ) :<br/>			foreach( $terms as $term ) :<br/>			echo &#039;&lt;p&gt;&lt;input type=&quot;radio&quot; id=&quot;&#039; . $term-&gt;term_id . &#039;&quot; value=&quot;&#039; . $term-&gt;term_id . &#039;&quot; name=&quot;category_filters&quot; class=&quot;category_filter&quot;/&gt;&lt;label for=&quot;&#039; . $term-&gt;term_id. &#039;&quot;&gt;&#039; . $term-&gt;name . &#039;&lt;/label&gt;&lt;/p&gt;&#039;;<br/>			endforeach;<br/>			endif;<br/>			?&gt;<br/>			&lt;!-- required hidden field for admin-ajax.php --&gt;<br/>			&lt;input type=&quot;hidden&quot; name=&quot;action&quot; value=&quot;ccfilter&quot; /&gt;<br/>		&lt;/form&gt;<br/>	&lt;/div&gt;<br/>	&lt;?php<br/>	$paged = (get_query_var(&#039;paged&#039;)) ? get_query_var(&#039;paged&#039;) : 1;<br/>	$args = array(<br/>		&#039;post_type&#039; =&gt; &#039;post&#039;,<br/>		&#039;post_status&#039; =&gt; &#039;publish&#039;,<br/>		&#039;posts_per_page&#039; =&gt; 5,<br/>		&#039;paged&#039; =&gt; $paged<br/><br/>	);<br/>	$query = new WP_Query( $args ); ?&gt;<br/>	&lt;?php <br/>	if ( $query-&gt;have_posts() ) :<br/>	$count = (int)0;?&gt;<br/>	&lt;div id=&quot;cc_posts_wrap&quot; class=&quot;flex-row&quot;&gt;<br/>		&lt;?php<br/>		while ( $query-&gt;have_posts() ) : $count++;<br/>		$query-&gt;the_post();<br/>		if($count == 1){ // Si c&#039;est le premier article de la liste, entour le d&#039;une clase 12 colonnes<br/>			$span = &#039;flex-col-xs-12&#039;;<br/>		}<br/>		if($count == 2 || $count == 3){// Si c&#039;est le deuxième et troisième article de la liste, entour le d&#039;une clase 6 colonnes<br/>			$span = &#039;flex-col-sm-6&#039;;<br/><br/>		}<br/>		if($count &gt; 3){ // sinon pour tous les suivants, répartis les en 3 colonnes<br/>			$span = &#039;flex-col-sm-4&#039;;<br/><br/>		}<br/>		//If its not 3 or higher, increase the count<br/>		$termsArray = get_the_terms($post-&gt;ID, &quot;category&quot;);  <br/>		$termsString =&quot;&quot;; <br/>		foreach ( $termsArray as $term ) {  <br/>			$termsString .= $term-&gt;slug;  <br/>		}<br/>		?&gt;<br/>		&lt;div  class=&quot;&lt;?php echo $termsString  .&#039; &#039; . $span ;?&gt; item&quot;&gt;<br/>			&lt;article  id=&quot;post-&lt;?php the_ID(); ?&gt;&quot; &lt;?php post_class();?&gt;&gt;<br/>				&lt;div class=&quot;post-featured-thumbnail&quot;&gt;<br/>					&lt;?php 	<br/>					if ( has_post_thumbnail() ) { <br/>						if($count == 1){<br/>							the_post_thumbnail(&#039;blog_featured&#039;);										<br/>						}else{<br/>							the_post_thumbnail();<br/>						}<br/>					}<br/><br/>					if ( &#039;post&#039; === get_post_type() ) :<br/>					?&gt;<br/>					&lt;div class=&quot;entry-meta&quot;&gt;<br/>						&lt;?php<br/>						numgrade_category_sticker(); 	<br/>						?&gt;<br/>					&lt;/div&gt;&lt;!-- .entry-meta --&gt;<br/><br/>					&lt;?php endif; ?&gt;<br/>				&lt;/div&gt;<br/><br/>				&lt;div class=&quot;post-content&quot;&gt;<br/>					&lt;header class=&quot;entry-header&quot;&gt;<br/>						&lt;?php<br/>						if ( is_singular() ) :<br/>						the_title( &#039;&lt;h1 class=&quot;entry-title&quot;&gt;&#039;, &#039;&lt;/h1&gt;&#039; );<br/>						else :<br/>						the_title( &#039;&lt;h2 class=&quot;entry-title&quot;&gt;&lt;a href=&quot;&#039; . esc_url( get_permalink() ) . &#039;&quot; rel=&quot;bookmark&quot;&gt;&#039;, &#039;&lt;/a&gt;&lt;/h2&gt;&#039; );<br/>						endif;<br/>						?&gt;<br/>					&lt;/header&gt;&lt;!-- .entry-header --&gt;<br/>					&lt;div class=&quot;entry-content&quot;&gt;<br/>						&lt;?php the_excerpt(); ?&gt;<br/>					&lt;/div&gt;&lt;!-- .entry-content --&gt;<br/>					&lt;?php <br/>					if($count == 1){ ?&gt;<br/>					&lt;div class=&quot;isotope-cta&quot;&gt;<br/>						&lt;a href=&quot;&lt;?php esc_url( the_permalink() );?&gt;&quot; rel=&quot;bookmark&quot;&gt;Lire&lt;/a&gt;<br/>					&lt;/div&gt;<br/>					&lt;?php } ?&gt;<br/>				&lt;/div&gt;<br/>				&lt;?php if($count != 1){ ?&gt;<br/>				&lt;div class=&quot;isotope-cta&quot;&gt;<br/>					&lt;a href=&quot;&lt;?php esc_url( the_permalink() );?&gt;&quot; rel=&quot;bookmark&quot;&gt;Lire&lt;/a&gt;<br/>				&lt;/div&gt;<br/>				&lt;?php } ?&gt;<br/>			&lt;/article&gt;&lt;!-- #post-&lt;?php the_ID(); ?&gt; --&gt;<br/>		&lt;/div&gt;<br/><br/><br/>		&lt;?php endwhile;?&gt;	<br/>	&lt;/div&gt; &lt;!-- end isotope-list --&gt;					<br/><br/>	&lt;?php	global $wp_query; <br/>	if (  $wp_query-&gt;max_num_pages &gt; 1 ) :<br/>	echo &#039;&lt;div class=&quot;loadmore_block&quot;&gt;&lt;div id=&quot;cc_loadmore&quot;&gt;Voir plus d\&#039;articles&lt;/div&gt;&lt;/div&gt;&#039;; <br/>	endif;<br/><br/>	else :<br/><br/>	get_template_part( &#039;template-parts/content&#039;, &#039;none&#039; );<br/><br/>	endif;<br/>	?&gt;<br/>&lt;/div&gt;&lt;!-- .flex-container --&gt;</code></pre> <div class="code-embed-infos"> </div> </div>
<h4>Le système de filtres</h4>
<p>Le système de filtres est assez simple, c&rsquo;est un code que l&rsquo;on peut retrouver un peu partout, notamment sur stackoverflow, puisque tout le monde se base sur les mêmes tutoriels, celui d&rsquo;<a href="https://www.aliciaramirez.com/2014/03/integrating-isotope-with-wordpress/">Alicia Ramirez</a> par exemple ! C&rsquo;est évidemment à personnaliser en fonction de ses besoins.</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;form action=&quot;#&quot; method=&quot;POST&quot; id=&quot;post_filters&quot;&gt;<br/>&lt;p&gt;&lt;input type=&quot;radio&quot; value=&quot;all&quot; id=&quot;all&quot; class=&quot;category_filter&quot; name=&quot;category_filters&quot;&gt;&lt;label for=&quot;all&quot;&gt;Toutes&lt;/label&gt;&lt;/p&gt;<br/>&lt;?php <br/>if( $terms = get_terms( array( &#039;taxonomy&#039; =&gt; &#039;category&#039; ) ) ) :<br/>foreach( $terms as $term ) :<br/>echo &#039;&lt;p&gt;&lt;input type=&quot;radio&quot; id=&quot;&#039; . $term-&gt;term_id . &#039;&quot; value=&quot;&#039; . $term-&gt;term_id . &#039;&quot; name=&quot;category_filters&quot; class=&quot;category_filter&quot;/&gt;&lt;label for=&quot;&#039; . $term-&gt;term_id. &#039;&quot;&gt;&#039; . $term-&gt;name . &#039;&lt;/label&gt;&lt;/p&gt;&#039;;<br/>endforeach;<br/>endif;<br/>?&gt;<br/>&lt;!-- required hidden field for admin-ajax.php --&gt;<br/>&lt;input type=&quot;hidden&quot; name=&quot;action&quot; value=&quot;ccfilter&quot; /&gt;<br/>&lt;/form&gt;</code></pre> <div class="code-embed-infos"> </div> </div>
<p>C&rsquo;est donc un simple formulaire, contenant un bouton radio « all » censé réinitialiser la recherche ou le filtrage. Ensuite dans une boucle on crée autant de boutons radios qu&rsquo;il y a de catégories, et pour chacune d&rsquo;entre elle, on récupère l&rsquo;id, le nom ou le slug.</p>
<p><strong>Il faut faire très attention aux noms données aux éléments :</strong> Choisissez des noms précis et gardez-les, il faut avoir un peu de rigueur là-dessus car on va les retrouver un peu partout dans le système :</p>
<ul>
<li>l&rsquo;ID du formulaire : <strong>id= »post_filters »</strong></li>
<li>le nom de nos boutons radio : <strong>name= »category_filters »</strong></li>
<li>la valeur du champ caché pour envoyer le formulaire: <strong>value= »ccfilter »</strong></li>
</ul>
<h4>L&rsquo;article en lui-même</h4>
<p>La boucle principale va donc nous ramener nos articles. Ici, comme précisé au début, j&rsquo;affiche grâce à un compteur que j&rsquo;incrémente, une disposition en colonne, comme sur l&rsquo;image. Le code est propre à mon projet, à vous de styliser ça à votre façon !</p>
<p>L&rsquo;essentiel, c&rsquo;est que l&rsquo;article soit disposé dans un conteneur, ici je lui donne l&rsquo;ID: <strong><em>id= »cc_posts_wrap »</em></strong>. Le <strong>système de filtres</strong>, ainsi que le <strong>bouton load more</strong> sont donc <strong>à l&rsquo;extérieur</strong> de ce conteneur.</p>
<h4>Le bouton load-more</h4>
<p>Enfin, tout à la fin on place notre bouton <em>load more</em></p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;?php	global $wp_query; <br/>if (  $wp_query-&gt;max_num_pages &gt; 1 ) :<br/>echo &#039;&lt;div class=&quot;loadmore_block&quot;&gt;&lt;div id=&quot;cc_loadmore&quot;&gt;Voir plus d\&#039;articles&lt;/div&gt;&lt;/div&gt;&#039;; <br/>				</code></pre> <div class="code-embed-infos"> </div> </div>
<h3>Le moteur des filtres et bu bouton ajax</h3>
<p>Voici tout le code à insérer dans <strong><em>functions.php</em></strong></p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">/*FUNCTION FILTER AND AJAX LOAD MORE*/<br/>add_action( &#039;wp_enqueue_scripts&#039;, &#039;cc_script_and_styles&#039;);<br/>function cc_script_and_styles() {<br/>	if ( is_home() || is_category() || is_archive()) {<br/>	global $wp_query;<br/>	wp_register_script( &#039;cc_scripts&#039;, get_stylesheet_directory_uri() . &#039;/js/script.js&#039;, array(&#039;jquery&#039;) );<br/>	wp_localize_script( &#039;cc_scripts&#039;, &#039;cc_loadmore_params&#039;, array(<br/>		&#039;ajaxurl&#039; =&gt; site_url() . &#039;/wp-admin/admin-ajax.php&#039;, // WordPress AJAX<br/>		&#039;posts&#039; =&gt; json_encode( $wp_query-&gt;query_vars ), // everything about your loop is here<br/>		&#039;current_page&#039; =&gt; $wp_query-&gt;query_vars[&#039;paged&#039;] ? $wp_query-&gt;query_vars[&#039;paged&#039;] : 1,<br/>		&#039;max_page&#039; =&gt; $wp_query-&gt;max_num_pages<br/>	) );<br/> <br/> 	wp_enqueue_script( &#039;cc_scripts&#039; );<br/> }<br/>}<br/>/*AJAX LOAD MORE AND FILTERS*/<br/>add_action(&#039;wp_ajax_loadmorebutton&#039;, &#039;cc_loadmore_ajax_handler&#039;);<br/>add_action(&#039;wp_ajax_nopriv_loadmorebutton&#039;, &#039;cc_loadmore_ajax_handler&#039;);<br/> <br/>function cc_loadmore_ajax_handler(){<br/>	$params = json_decode( stripslashes( $_POST[&#039;query&#039;] ), true ); <br/>	$params[&#039;paged&#039;] = $_POST[&#039;page&#039;] + 1; <br/>	$params[&#039;post_status&#039;] = &#039;publish&#039;;<br/>	query_posts( $params );<br/><br/>	if( have_posts() ) :<br/>		while( have_posts() ): the_post();<br/>			$termsArray = get_the_terms($post-&gt;ID, &quot;category&quot;);  <br/>			 $termsString =&quot;&quot;; <br/>			 foreach ( $termsArray as $term ) {<br/>			 $termsString .= $term-&gt;slug;  <br/>			 }<br/>			 ?&gt;<br/> 			&lt;div  class=&quot;&lt;?php echo $termsString ;?&gt; flex-col-sm-4 item&quot;&gt;<br/>				&lt;article  id=&quot;post-&lt;?php the_ID(); ?&gt;&quot; &lt;?php post_class();?&gt;&gt;<br/>					&lt;div class=&quot;post-featured-thumbnail&quot;&gt;<br/>						&lt;?php 	<br/>							if ( has_post_thumbnail() ) { <br/>						<br/>						 		the_post_thumbnail();<br/>						 	}<br/>						 if ( &#039;post&#039; === get_post_type() ) :<br/>							?&gt;<br/>							&lt;div class=&quot;entry-meta&quot;&gt;<br/>								&lt;?php<br/>								numgrade_category_sticker(); 	<br/>								?&gt;<br/>							&lt;/div&gt;&lt;!-- .entry-meta --&gt;<br/>						&lt;?php endif; ?&gt;<br/>					&lt;/div&gt;<br/>					&lt;div class=&quot;post-content&quot;&gt;<br/>						&lt;header class=&quot;entry-header&quot;&gt;<br/>							&lt;?php<br/>								the_title( &#039;&lt;h2 class=&quot;entry-title&quot;&gt;&lt;a href=&quot;&#039; . esc_url( get_permalink() ) . &#039;&quot; rel=&quot;bookmark&quot;&gt;&#039;, &#039;&lt;/a&gt;&lt;/h2&gt;&#039; );<br/>							?&gt;<br/>						&lt;/header&gt;&lt;!-- .entry-header --&gt;<br/>						&lt;div class=&quot;entry-content&quot;&gt;<br/>							&lt;?php the_excerpt(); ?&gt;<br/>						&lt;/div&gt;&lt;!-- .entry-content --&gt;<br/>					&lt;/div&gt;<br/>					&lt;div class=&quot;isotope-cta&quot;&gt;<br/>							&lt;a href=&quot;&lt;?php esc_url( the_permalink() );?&gt;&quot; rel=&quot;bookmark&quot;&gt;Lire&lt;/a&gt;<br/>						&lt;/div&gt;<br/>				&lt;/article&gt;&lt;!-- #post-&lt;?php the_ID(); ?&gt; --&gt;<br/>			&lt;/div&gt;<br/>			&lt;?php<br/>		endwhile;<br/>	endif;<br/>	die; <br/>}<br/> <br/>add_action(&#039;wp_ajax_ccfilter&#039;, &#039;cc_filter_function&#039;); <br/>add_action(&#039;wp_ajax_nopriv_ccfilter&#039;, &#039;cc_filter_function&#039;);<br/> <br/>function cc_filter_function(){<br/>    if( isset( $_POST[&#039;all&#039;] ) )<br/>    	$terms = get_terms( array( &#039;taxonomy&#039; =&gt; &#039;category&#039; ) );<br/>            $args[&#039;tax_query&#039;] = array(<br/>                array(<br/>                    &#039;taxonomy&#039; =&gt; &#039;category&#039;,<br/>                    &#039;field&#039; =&gt; &#039;id&#039;,<br/>                    &#039;terms&#039; =&gt; $terms,<br/>                    &quot;posts_per_page&quot; =&gt; 5<br/>                )<br/>            );<br/>	if( isset( $_POST[&#039;category_filters&#039;] ) )<br/>	    $args[&#039;tax_query&#039;] = array(<br/>	        array(<br/>	            &#039;taxonomy&#039; =&gt; &#039;category&#039;,<br/>	            &#039;field&#039; =&gt; &#039;id&#039;,<br/>	            &#039;terms&#039; =&gt; $_POST[&#039;category_filters&#039;],<br/>	            &quot;posts_per_page&quot; =&gt; 5<br/>	        )<br/>	    );<br/>		query_posts( $args );<br/>	global $wp_query;<br/>	if( have_posts() ) : $count = (int)0;<br/> 		ob_start(); <br/>		while( have_posts() ): $count++;<br/>		the_post();<br/> 		if($count == 1){<br/>				$span = &#039;flex-col-xs-12&#039;;<br/>			}<br/>			if($count == 2 || $count == 3){<br/>		   	$span = &#039;flex-col-sm-6&#039;;<br/>			}<br/>			if($count &gt; 3){<br/>		   	$span = &#039;flex-col-sm-4&#039;;<br/>			}<br/>			 $termsArray = get_the_terms($post-&gt;ID, &quot;category&quot;);  <br/>			 $termsString =&quot;&quot;; <br/>			 foreach ( $termsArray as $term ) { <br/>			 $termsString .= $term-&gt;slug;  <br/>			 }<br/>			 ?&gt;<br/> 			 &lt;div  class=&quot;&lt;?php echo $termsString  .&#039; &#039; . $span ;?&gt; item&quot;&gt;<br/>				&lt;article  id=&quot;post-&lt;?php the_ID(); ?&gt;&quot; &lt;?php post_class();?&gt;&gt;<br/>					&lt;div class=&quot;post-featured-thumbnail&quot;&gt;<br/>						&lt;?php 	<br/>							if ( has_post_thumbnail() ) { <br/>								if($count == 1){<br/>						 		the_post_thumbnail(&#039;blog_featured&#039;);										<br/>							}else{<br/>						 		the_post_thumbnail();<br/>						 	}<br/>						}			 <br/>						 if ( &#039;post&#039; === get_post_type() ) :<br/>							?&gt;<br/>							&lt;div class=&quot;entry-meta&quot;&gt;<br/>								&lt;?php<br/>								numgrade_category_sticker(); 	<br/>								?&gt;<br/>							&lt;/div&gt;&lt;!-- .entry-meta --&gt;<br/>						&lt;?php endif; ?&gt;<br/>					&lt;/div&gt;<br/>					&lt;div class=&quot;post-content&quot;&gt;<br/>						&lt;header class=&quot;entry-header&quot;&gt;<br/>							&lt;?php<br/>							if ( is_singular() ) :<br/>								the_title( &#039;&lt;h1 class=&quot;entry-title&quot;&gt;&#039;, &#039;&lt;/h1&gt;&#039; );<br/>							else :<br/>								the_title( &#039;&lt;h2 class=&quot;entry-title&quot;&gt;&lt;a href=&quot;&#039; . esc_url( get_permalink() ) . &#039;&quot; rel=&quot;bookmark&quot;&gt;&#039;, &#039;&lt;/a&gt;&lt;/h2&gt;&#039; );<br/>							endif;<br/>							?&gt;<br/>						&lt;/header&gt;&lt;!-- .entry-header --&gt;<br/>						&lt;div class=&quot;entry-content&quot;&gt;<br/>							&lt;?php the_excerpt(); ?&gt;<br/>						&lt;/div&gt;&lt;!-- .entry-content --&gt;<br/>						&lt;?php <br/>						if($count == 1){ ?&gt;<br/>							&lt;div class=&quot;isotope-cta&quot;&gt;<br/>								&lt;a href=&quot;&lt;?php esc_url( the_permalink() );?&gt;&quot; rel=&quot;bookmark&quot;&gt;Lire&lt;/a&gt;<br/>							&lt;/div&gt;<br/>						&lt;?php } ?&gt;<br/>					&lt;/div&gt;<br/>					&lt;?php if($count != 1){ ?&gt;<br/>					&lt;div class=&quot;isotope-cta&quot;&gt;<br/>						&lt;a href=&quot;&lt;?php esc_url( the_permalink() );?&gt;&quot; rel=&quot;bookmark&quot;&gt;Lire&lt;/a&gt;<br/>					&lt;/div&gt;<br/>					&lt;?php } ?&gt;<br/>				&lt;/article&gt;&lt;!-- #post-&lt;?php the_ID(); ?&gt; --&gt;<br/>			&lt;/div&gt;<br/>			&lt;?php<br/>		endwhile;<br/> 		$posts_html = ob_get_contents(); <br/>   		ob_end_clean(); <br/>	else:<br/>		$posts_html = &#039;&lt;p&gt;Aucun résultat&lt;/p&gt;&#039;;<br/>	endif;<br/><br/> 	echo json_encode( array(<br/>		&#039;posts&#039; =&gt; json_encode( $wp_query-&gt;query_vars ),<br/>		&#039;max_page&#039; =&gt; $wp_query-&gt;max_num_pages,<br/>		&#039;found_posts&#039; =&gt; $wp_query-&gt;found_posts,<br/>		&#039;content&#039; =&gt; $posts_html<br/>	) );<br/>	die();<br/>}</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Le code est à diviser en trois étapes:</p>
<h3>1-D&rsquo;abord, l&rsquo;appel aux scripts ajax de wordpress</h3>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">add_action( &#039;wp_enqueue_scripts&#039;, &#039;cc_script_and_styles&#039;);<br/>function cc_script_and_styles() {<br/>	if ( is_home() || is_category() || is_archive()) {<br/>	global $wp_query;<br/>	wp_register_script( &#039;cc_scripts&#039;, get_stylesheet_directory_uri() . &#039;/js/script.js&#039;, array(&#039;jquery&#039;) );<br/>	wp_localize_script( &#039;cc_scripts&#039;, &#039;cc_loadmore_params&#039;, array(<br/>		&#039;ajaxurl&#039; =&gt; site_url() . &#039;/wp-admin/admin-ajax.php&#039;, // WordPress AJAX<br/>		&#039;posts&#039; =&gt; json_encode( $wp_query-&gt;query_vars ), // everything about your loop is here<br/>		&#039;current_page&#039; =&gt; $wp_query-&gt;query_vars[&#039;paged&#039;] ? $wp_query-&gt;query_vars[&#039;paged&#039;] : 1,<br/>		&#039;max_page&#039; =&gt; $wp_query-&gt;max_num_pages<br/>	) );<br/> <br/> 	wp_enqueue_script( &#039;cc_scripts&#039; );<br/> }<br/>}<br/><br/>/*AJAX LOAD MORE AND FILTERS*/<br/>add_action(&#039;wp_ajax_loadmorebutton&#039;, &#039;cc_loadmore_ajax_handler&#039;);<br/>add_action(&#039;wp_ajax_nopriv_loadmorebutton&#039;, &#039;cc_loadmore_ajax_handler&#039;);</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Dans notre fonction <strong><em>wp_enqueue_script</em></strong>, on fait appel à un premier fichier js qui va contenir tout le code nécessaire au bon fonctionnement du système de filtre et du rechargement ajax des articles. On voit ca juste après.</p>
<p>Puis on charge le fichier &lsquo;<strong><em>admin-ajax.php</em></strong>&lsquo; intégré par défaut dans wordpress.</p>
<p>Vous pouvez voir que j&rsquo;entoure l&rsquo;appel au script d&rsquo;une condition :</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">if ( is_home() || is_category() || is_archive()) {...}</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Comme j&rsquo;utilise ce système aussi pour des custom post type, je limite ici l&rsquo;appel des scripts au blog, aux catégories et aux archives puisque j&rsquo;utilise ce même script pour mes catégories et mes archives. Comme l&rsquo;appel au script ajax est différent pour les custom post type, j&rsquo;évite ainsi une interférence entre les deux.</p>
<h3>2-Ajax load more button</h3>
<p>Les deux lignes de codes qui suivent nous servent à créer nos actions ajax. Les premières serviront au bouton<em> ajax load more</em>, et plus bas dans le code, on va retrouver la même chose mais cette fois pour les filtres ajax.</p>
<p>Dans notre <em><strong>add_action</strong></em> et pour faire fonctionner notre ajax, les deux « mots clés » <strong><em>wp_ajax_ »</em></strong> et « <em><strong>wp_ajax_nopriv_ »</strong></em> sont obligatoires, et ils doivent être suivis du nom de votre action.</p>
<p>Pour le bouton load_more, je leur donne un nom significatif « <em> loadmorebutton</em>« . Le nom donné en deuxième argument : « <em>cc_loadmore_ajax_handler</em> » est le nom de la fonction située juste en dessous.</p>
<p>Comme on le voit, cette fonction « <strong><em>function cc_loadmore_ajax_handler(){ }</em></strong> » contient une boucle pour afficher mes articles. Ici, je n&rsquo;ai pas besoin de reproduire l&rsquo;affichage avec différentes tailles de colonnes. Comme les articles doivent s&rsquo;afficher à la suite, je souhaite plutôt conserver un affichage homogène avec les derniers articles. Ils s&rsquo;afficheront donc normalement, c&rsquo;est à dire en 3 colonnes.</p>
<h3>Filters functions</h3>
<p>Ensuite vient le code pour le filtrage des articles.</p>
<p>Ici, on retrouve les deux mots clés obligatoires, suivi du nom de mes actions :</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">add_action(&#039;wp_ajax_ccfilter&#039;, &#039;cc_filter_function&#039;); <br/>add_action(&#039;wp_ajax_nopriv_ccfilter&#039;, &#039;cc_filter_function&#039;);</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Le nom de l&rsquo;action donné ici:  « <strong>ccfilter</strong>« , doit être le même que celui de la valeur de mon champs caché dans le formulaire de filtrage, souvenez-vous.</p>
<div class="code-embed-wrapper"> <pre class="language-markup code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-markup code-embed-code">	&lt;!-- required hidden field for admin-ajax.php --&gt;<br/>&lt;input type=&quot;hidden&quot; name=&quot;action&quot; value=&quot;ccfilter&quot; /&gt;</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Comme à chaque clic sur un bouton de filtrage la page devra « effacer les articles » pour afficher ceux d&rsquo;une autre catégorie, je souhaite conserver mon affichage original montré dans l&rsquo;image. La boucle est donc exactement la même que dans mon fichier index.php (ou home.php)</p>
<p>Pour le bouton « all », c&rsquo;est assez simple en fait, on crée un boucle sans distinction de catégorie :</p>
<p>On ramène toutes les catégories, avec <em>get_terms </em>suivi du nom de la taxonomie qui est ici category (système classique de wordpress). On aurait aussi pu faire un simple get_categories().</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">$terms = get_terms( array( &#039;taxonomy&#039; =&gt; &#039;category&#039; ) );</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Dans les arguments de la requête, on ne fait pas de distinction :</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&#039;terms&#039; =&gt; $terms,</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Dans la boucle suivante par contre, on fait en sorte de distinguer chaque catégorie avec un tax_query().</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">tax_query:: $args[&#039;tax_query&#039;] = array(<br/>array(</code></pre> <div class="code-embed-infos"> </div> </div>
<p>et dans les arguments, on ramène la catégorie qui a été sélectionnée par l&rsquo;utilisateur :</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&#039;terms&#039; =&gt; $_POST[&#039;category_filters&#039;],</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Notez que cette deuxième grande boucle est entourée des tags</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">ob_start(); <br/> (...)<br/>$posts_html = ob_get_contents(); <br/>  ob_end_clean(); <br/>(...)<br/><br/><br/>echo json_encode( array(<br/>		&#039;posts&#039; =&gt; json_encode( $wp_query-&gt;query_vars ),<br/>		&#039;max_page&#039; =&gt; $wp_query-&gt;max_num_pages,<br/>		&#039;found_posts&#039; =&gt; $wp_query-&gt;found_posts,<br/>		&#039;content&#039; =&gt; $posts_html<br/>	) );<br/> 	<br/>	die();</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Vous pouvez vous référer à l&rsquo;article cité ou aller sur <a href="https://www.php.net/manual/fr/function.ob-start.php">php.net</a> pour comprendre l&rsquo;utilité des fonctions <em>ob_start();</em> <em>ob_end_clean();</em> et <em>ob_get_contents(); </em></p>
<h3>Les fonctions js</h3>
<p>Dans notre fonction <em>wp_enqueue_script</em>, on a vu qu&rsquo;on faisait appel à un fichier js</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">wp_register_script( &#039;cc_scripts&#039;, get_stylesheet_directory_uri() . &#039;/js/script.js&#039;, array(&#039;jquery&#039;) );</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Il va donc falloir créer ce fichier. Donnez-lui le nom que vous voulez, bien sûr le même que dans cette fonction <em>wp_register_script().</em></p>
<p>Et voici donc tout le code à insérer dans le fichier js</p>
<div class="code-embed-wrapper"> <pre class="language-javascript code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-javascript code-embed-code"> jQuery(function($){<br/><br/>	 /* LOAD MORE FUNCTION ON FORMATION ARCHIVE PAGE */<br/>	 $(&#039;#cc_loadmore&#039;).click(function(){<br/><br/>		 $.ajax({<br/>			 url : cc_loadmore_params.ajaxurl, // AJAX handler<br/>			 data : {<br/>				 &#039;action&#039;: &#039;loadmorebutton&#039;, // le paramètre pour admin-ajax.php<br/>				 &#039;query&#039;: cc_loadmore_params.posts, // le paramètre de la loop utilisée par wp_localize_script()<br/>				 &#039;page&#039; : cc_loadmore_params.current_page // la page en cours<br/>			 },<br/>			 type : &#039;POST&#039;,<br/>			 beforeSend : function ( xhr ) {<br/>				 $(&#039;#cc_loadmore&#039;).text(&#039;Recherche...&#039;); // mettre ici let exte de son choix pour le chargement des articles<br/>			 },<br/>			 success : function( posts ){<br/>				 if( posts ) {<br/><br/>					 $(&#039;#cc_loadmore&#039;).text( &#039;Voir plus d\&#039;articles&#039; );<br/>					 $(&#039;#cc_posts_wrap&#039;).append( posts ); // on &quot;append&quot; les articles supplémentaires<br/>					 cc_loadmore_params.current_page++;<br/><br/>					 if ( cc_loadmore_params.current_page == cc_loadmore_params.max_page ) <br/>						 $(&#039;#cc_loadmore&#039;).hide(); // on cache le bouton s&#039;il n&#039;y a plus d&#039;articles<br/><br/>				 } else {<br/>					 $(&#039;#cc_loadmore&#039;).hide(); // s&#039;il n&#039;y a rien à afficher on cache le bouton<br/>				 }<br/>			 }<br/>		 });<br/>		 return false;<br/>	 });<br/>          /* FILTERING FUNCTION ON FORMATION ARCHIVE PAGE */<br/>            $(&#039;#post_filters&#039;).change(function(){<br/><br/>              $.ajax({<br/>                url : cc_loadmore_params.ajaxurl,<br/>                data : $(&#039;#post_filters&#039;).serialize(), // form data<br/>                dataType : &#039;json&#039;, // on utilise le format json pour passer directement côté serveur<br/>                type : &#039;POST&#039;,<br/><br/>                success : function( data ){<br/>                  <br/>                  cc_loadmore_params.current_page = 1; <br/>                  <br/>                  cc_loadmore_params.posts = data.posts;<br/>                 <br/>                  cc_loadmore_params.max_page = data.max_page; <br/>                  <br/>                  $(&#039;#cc_posts_wrap&#039;).html(data.content); <br/>               <br/>                  if ( data.max_page &lt; 2 ) {<br/>                    $(&#039;#cc_loadmore&#039;).hide();<br/>                  } else {<br/>                    $(&#039;#cc_loadmore&#039;).show();<br/>                  }<br/>                }<br/>              });<br/>              // return folse pour ne pas envoyer le formulaire<br/>              return false;<br/>           <br/>            });<br/>});</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Comme on le voit ici , on retrouve les différents noms donnés à nos élements :</p>
<p><strong><em>#cc_loadmore</em></strong> c&rsquo;est l&rsquo;ID de notre bouton ajax load more dans notre fichier index.php ou home.php.</p>
<p><em><strong> &lsquo;action&rsquo;: &lsquo;loadmorebutton&rsquo;,</strong></em> c&rsquo;est donc le nom de notre action ajax,</p>
<p><strong><em>cc_loadmore_params </em></strong>c&rsquo;est le nom donné en argument à notre fonction <em>wp_localize_script()</em></p>
<p><strong><em>#cc_posts_wrap </em></strong>c&rsquo;est le nom de notre conteneur principal, dans notre fichier index.php ou home.php.</p>
<p><em><strong>#post_filters</strong></em>, c&rsquo;est l&rsquo;ID de notre formulaire de filtrage.</p>
<h3>Utiliser le même système pour ses pages d&rsquo;archives</h3>
<p>Pour aller plus loin, vous pouvez aussi faire fonctionner votre bouton ajax load more dans vos pages d&rsquo;archives.</p>
<p>Je mets ici tout le code d&rsquo;une page archive, dans laquelle j&rsquo;intègre ce bouton. C&rsquo;est le même css finalement que dans la page blog, et on utilise le même appel au script js. J&rsquo;utilise donc la fonction <strong><em>function cc_loadmore_ajax_handler(){}</em></strong> et la boucle contenue à l&rsquo;intérieur</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;?php get_header(); ?&gt;<br/><br/>	&lt;div id=&quot;primary&quot; class=&quot;content-area&quot;&gt;<br/>		&lt;main id=&quot;main&quot; class=&quot;site-main&quot;&gt;<br/>			&lt;div class=&quot;flex-container&quot;&gt;<br/>				&lt;div class=&quot;flex-row&quot;&gt;	<br/>					&lt;?php  if ( have_posts() ) : ?&gt;<br/><br/>					&lt;header class=&quot;page-header&quot;&gt;<br/>						&lt;?php<br/>						the_archive_title( &#039;&lt;h1 class=&quot;page-title&quot;&gt;&#039;, &#039;&lt;/h1&gt;&#039; );<br/>						the_archive_description( &#039;&lt;div class=&quot;archive-description&quot;&gt;&#039;, &#039;&lt;/div&gt;&#039; );<br/>						?&gt;<br/>					&lt;/header&gt;&lt;!-- .page-header --&gt;<br/>				&lt;/div&gt;<br/>				<br/>				&lt;div id=&quot;cc_posts_wrap&quot; class=&quot;flex-row&quot;&gt;<br/>				&lt;?php<br/>				/* Start the Loop */<br/>				while ( have_posts() ) : the_post(); ?&gt;<br/><br/>					&lt;div  class=&quot;flex-col-sm-6 flex-col-md-4 item&quot;&gt;<br/>						&lt;article  id=&quot;post-&lt;?php the_ID(); ?&gt;&quot; &lt;?php post_class();?&gt;&gt;<br/>							&lt;div class=&quot;post-featured-thumbnail&quot;&gt;<br/>								&lt;?php 	<br/>								if ( has_post_thumbnail() ) { <br/>									if($count == 1){<br/>										the_post_thumbnail(&#039;blog_featured&#039;);										<br/>									}else{<br/>										the_post_thumbnail();<br/>									}<br/>								}<br/><br/>								if ( &#039;post&#039; === get_post_type() ) :<br/>								?&gt;<br/>								&lt;div class=&quot;entry-meta&quot;&gt;<br/>									&lt;?php<br/>									numgrade_category_sticker(); 	<br/>									?&gt;<br/>								&lt;/div&gt;&lt;!-- .entry-meta --&gt;<br/><br/>								&lt;?php endif; ?&gt;<br/>							&lt;/div&gt;<br/><br/>							&lt;div class=&quot;post-content&quot;&gt;<br/>								&lt;header class=&quot;entry-header&quot;&gt;<br/>									&lt;?php<br/>									if ( is_singular() ) :<br/>									the_title( &#039;&lt;h1 class=&quot;entry-title&quot;&gt;&#039;, &#039;&lt;/h1&gt;&#039; );<br/>									else :<br/>									the_title( &#039;&lt;h2 class=&quot;entry-title&quot;&gt;&lt;a href=&quot;&#039; . esc_url( get_permalink() ) . &#039;&quot; rel=&quot;bookmark&quot;&gt;&#039;, &#039;&lt;/a&gt;&lt;/h2&gt;&#039; );<br/>									endif;<br/>									?&gt;<br/>								&lt;/header&gt;&lt;!-- .entry-header --&gt;<br/>								&lt;div class=&quot;entry-content&quot;&gt;<br/>									&lt;?php the_excerpt(); ?&gt;<br/>								&lt;/div&gt;&lt;!-- .entry-content --&gt;<br/><br/><br/>							&lt;/div&gt;<br/><br/>							&lt;div class=&quot;isotope-cta&quot;&gt;<br/>								&lt;a href=&quot;&lt;?php esc_url( the_permalink() );?&gt;&quot; rel=&quot;bookmark&quot;&gt;Lire&lt;/a&gt;<br/>							&lt;/div&gt;<br/><br/>						&lt;/article&gt;&lt;!-- #post-&lt;?php the_ID(); ?&gt; --&gt;<br/>					&lt;/div&gt;<br/><br/>		&lt;?php	endwhile;?&gt;<br/>		&lt;/div&gt; &lt;!-- end isotope-list --&gt;<br/>		&lt;?php<br/>			global $wp_query; // you can remove this line if everything works for you<br/>			if (  $wp_query-&gt;max_num_pages &gt; 1 ) :<br/>				echo &#039;&lt;div class=&quot;loadmore_block&quot;&gt;&lt;div id=&quot;cc_loadmore&quot;&gt;Voir plus d\&#039;articles&lt;/div&gt;&lt;/div&gt;&#039;; // you can use &lt;a&gt; as well<br/>			endif;<br/>		else :<br/>			get_template_part( &#039;template-parts/content&#039;, &#039;none&#039; );<br/><br/>		endif;<br/>		?&gt;<br/>				&lt;/div&gt;&lt;!-- .flex-container --&gt;<br/>		&lt;/main&gt;&lt;!-- #main --&gt;<br/>	&lt;/div&gt;&lt;!-- #primary --&gt;<br/><br/>&lt;?php<br/><br/>get_footer();?&gt;</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Dans un prochain article, on va voir comment pousser encore plus loin et faisant la même chose avec les custom  post type.</p>
<h3>Recommandations :</h3>
<p>Si malgré tout ce code vous ne parvenez pas à faire marcher le bouton loadmore en ajax ou le système de filtres, je vous invite à consulter les nombreux commentaires sur les pages suivantes :  <a href="https://rudrastyh.com/wordpress/load-more-posts-ajax.html">loadmore</a>, <a href="https://rudrastyh.com/wordpress/ajax-post-filters.html">filters</a>,  <a href="https://rudrastyh.com/wordpress/ajax-load-more-with-filters.html">ajax et filtres</a>, <a href="https://rudrastyh.com/wordpress/load-more-and-pagination.html">load more et pagination</a>. De nombreux internautes posent des questions et d&rsquo;autres y répondent. Vous devriez y trouver des pistes !</p>
<p>Si vous rencontrez un problème lors de l&rsquo;affichage des articles, notamment au niveau du nombre de posts affichés, changez le paramètre « posts_per_page » et modifiez également les options dans le backoffice de wordpress dans Réglages / Lecture.</p>
<p>The post <a rel="nofollow" href="https://www.copier-coller.com/filtrer-ses-articles-et-ajouter-un-bouton-loadmore/">Filtrer ses articles et ajouter un bouton « loadmore »</a> appeared first on <a rel="nofollow" href="https://www.copier-coller.com">Copier coller</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.copier-coller.com/filtrer-ses-articles-et-ajouter-un-bouton-loadmore/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Créer des blocs de différentes tailles dans vos pages d&#8217;archives</title>
		<link>https://www.copier-coller.com/creer-des-blocs-de-differentes-tailles-dans-vos-pages-darchives/</link>
					<comments>https://www.copier-coller.com/creer-des-blocs-de-differentes-tailles-dans-vos-pages-darchives/#respond</comments>
		
		<dc:creator><![CDATA[copier coller]]></dc:creator>
		<pubDate>Wed, 15 Apr 2020 18:04:56 +0000</pubDate>
				<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://www.copier-coller.com/?p=6071</guid>

					<description><![CDATA[<p>Aujourd&#8217;hui on va voir ou revoir une façon de disposer ses blocs d&#8217;articles différemment. Dans un thème classique, toutes les vignettes d&#8217;articles sont réparties de manière équivalentes, faisant toutes la même taille et la même largeur. Voici ce à quoi on veut parvenir Le schéma a été fait rapidement, mais en gros on veut obtenir [...]</p>
<p>The post <a rel="nofollow" href="https://www.copier-coller.com/creer-des-blocs-de-differentes-tailles-dans-vos-pages-darchives/">Créer des blocs de différentes tailles dans vos pages d&rsquo;archives</a> appeared first on <a rel="nofollow" href="https://www.copier-coller.com">Copier coller</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Comment créer des pages d&rsquo;archives originales ?</h2>
<p>Aujourd&rsquo;hui on va voir ou revoir une façon de disposer ses blocs d&rsquo;articles différemment.</p>
<p>Dans un thème classique, toutes les vignettes d&rsquo;articles sont réparties de manière équivalentes, faisant toutes la même taille et la même largeur.</p>
<h3>Le schéma</h3>
<p>Voici ce à quoi on veut parvenir</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6072" src="https://www.copier-coller.com/wp-content/uploads/2020/04/custom-design-wordpress.jpg" alt="custom design wordpress" width="921" height="773" srcset="https://www.copier-coller.com/wp-content/uploads/2020/04/custom-design-wordpress.jpg 921w, https://www.copier-coller.com/wp-content/uploads/2020/04/custom-design-wordpress-300x252.jpg 300w, https://www.copier-coller.com/wp-content/uploads/2020/04/custom-design-wordpress-768x645.jpg 768w, https://www.copier-coller.com/wp-content/uploads/2020/04/custom-design-wordpress-624x524.jpg 624w" sizes="(max-width: 921px) 100vw, 921px" /></p>
<p>Le schéma a été fait rapidement, mais en gros on veut obtenir une première vignette qui s&rsquo;étend sur 12 colonnes, puis 6, puis 4.</p>
<p>Je donne d&rsquo;autres exemples d&rsquo;affichages originaux dans des précédents articles, <a href="https://www.copier-coller.com/ajouter-row-x-articles-wordpress/">ici,</a> <a href="https://www.copier-coller.com/alterner-laffichage-de-ses-articles-wordpress-avec-bootstrap/">là</a>, ou encore <a href="https://www.copier-coller.com/differencier-laffichage-des-articles/">ici</a>.</p>
<h3>Le code</h3>
<p>Ici, je n&rsquo;utilise pas bootstrap, mais une grille flexbox équivalente. Vous pouvez la retrouver <a href="https://www.copier-coller.com/flex-un-exemple-de-grille/">ici.</a></p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">&lt;?php<br/>				$paged = (get_query_var(&#039;paged&#039;)) ? get_query_var(&#039;paged&#039;) : 1;<br/>				$args = array(<br/>				    &#039;post_type&#039; =&gt; &#039;post&#039;,<br/>				    &#039;post_status&#039; =&gt; &#039;publish&#039;,<br/>				    &#039;posts_per_page&#039; =&gt; 5,<br/>				    &#039;paged&#039; =&gt; $paged<br/>				   <br/>				);<br/>				$query = new WP_Query( $args ); ?&gt;<br/>				&lt;?php <br/>				if ( $query-&gt;have_posts() ) :<br/>				$count = (int)0;?&gt;<br/>				  	&lt;div id=&quot;cc_posts_wrap&quot; class=&quot;flex-row&quot;&gt;<br/>						&lt;?php<br/>						while ( $query-&gt;have_posts() ) : $count++;<br/>							$query-&gt;the_post();<br/>							if($count == 1){<br/>								$span = &#039;flex-col-xs-12&#039;;<br/>								<br/>								<br/>								<br/>							}<br/>							if($count == 2 || $count == 3){<br/>						   	$span = &#039;flex-col-sm-6&#039;;<br/>						   	<br/>							}<br/>							if($count &gt; 3){<br/>						   	$span = &#039;flex-col-sm-4&#039;;<br/>						   	<br/>							}<br/>							//If its not 3 or higher, increase the count<br/>							$termsArray = get_the_terms($post-&gt;ID, &quot;category&quot;);  //Get the terms for this particular item<br/>							 $termsString =&quot;&quot;; //initialize the string that will contain the terms<br/>							 foreach ( $termsArray as $term ) { // for each term <br/>							 $termsString .= $term-&gt;slug;  <br/>							 }<br/>						?&gt;<br/>								 &lt;div  class=&quot;&lt;?php echo $termsString  .&#039; &#039; . $span ;?&gt; item&quot;&gt;<br/>									&lt;article  id=&quot;post-&lt;?php the_ID(); ?&gt;&quot; &lt;?php post_class();?&gt;&gt;<br/>										&lt;div class=&quot;post-featured-thumbnail&quot;&gt;<br/>											&lt;?php 	<br/>												if ( has_post_thumbnail() ) { <br/>													if($count == 1){<br/>											 		the_post_thumbnail(&#039;blog_featured&#039;);										<br/>												}else{<br/>											 		the_post_thumbnail();<br/>											 	}<br/>											}<br/>											 <br/>											 if ( &#039;post&#039; === get_post_type() ) :<br/>												?&gt;<br/>												&lt;div class=&quot;entry-meta&quot;&gt;<br/>													&lt;?php<br/>													numgrade_category_sticker(); 	<br/>													?&gt;<br/>												&lt;/div&gt;&lt;!-- .entry-meta --&gt;<br/><br/>											&lt;?php endif; ?&gt;<br/>										&lt;/div&gt;<br/><br/>										&lt;div class=&quot;post-content&quot;&gt;<br/>											&lt;header class=&quot;entry-header&quot;&gt;<br/>												&lt;?php<br/>												if ( is_singular() ) :<br/>													the_title( &#039;&lt;h1 class=&quot;entry-title&quot;&gt;&#039;, &#039;&lt;/h1&gt;&#039; );<br/>												else :<br/>													the_title( &#039;&lt;h2 class=&quot;entry-title&quot;&gt;&lt;a href=&quot;&#039; . esc_url( get_permalink() ) . &#039;&quot; rel=&quot;bookmark&quot;&gt;&#039;, &#039;&lt;/a&gt;&lt;/h2&gt;&#039; );<br/>												endif;<br/>												?&gt;<br/>											&lt;/header&gt;&lt;!-- .entry-header --&gt;<br/>											&lt;div class=&quot;entry-content&quot;&gt;<br/>												&lt;?php the_excerpt(); ?&gt;<br/>											&lt;/div&gt;&lt;!-- .entry-content --&gt;<br/>											&lt;?php <br/>											if($count == 1){ ?&gt;<br/>												&lt;div class=&quot;isotope-cta&quot;&gt;<br/>													&lt;a href=&quot;&lt;?php esc_url( the_permalink() );?&gt;&quot; rel=&quot;bookmark&quot;&gt;Lire&lt;/a&gt;<br/>												&lt;/div&gt;<br/>											&lt;?php } ?&gt;<br/>										&lt;/div&gt;<br/>										&lt;?php if($count != 1){ ?&gt;<br/>										&lt;div class=&quot;isotope-cta&quot;&gt;<br/>											&lt;a href=&quot;&lt;?php esc_url( the_permalink() );?&gt;&quot; rel=&quot;bookmark&quot;&gt;Lire&lt;/a&gt;<br/>										&lt;/div&gt;<br/>										&lt;?php } ?&gt;<br/>									&lt;/article&gt;&lt;!-- #post-&lt;?php the_ID(); ?&gt; --&gt;<br/>								&lt;/div&gt;<br/><br/><br/>				&lt;?php		endwhile;<br/>				?&gt;	<br/>				&lt;/div&gt; &lt;!-- end isotope-list --&gt;		</code></pre> <div class="code-embed-infos"> </div> </div>
<p>L&rsquo;idée pour ce genre de cas est toujours la même. On crée notre boucle, et à l&rsquo;intérieur, on crée un compteur qu&rsquo;on va incrémenter. Dans ce cas particulier, on place nos différentes tailles de colonnes dans une variable, et on dit : »si c&rsquo;est le premier article, entoure mon article d&rsquo;une classe « flex-col-sm-12 » (12 colonnes), Si ce sont les deuxième et troisième article, entour les d&rsquo;une classe « flex-col-sm-6 ». Puis, pour toutes les autres, attribue leur une classe « flex-col-sm-4 » pour créer 3 colonnes.</p>
<p>A vous ensuite de styliser le tout pour un rendu optimal, comme ici.</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6073" src="https://www.copier-coller.com/wp-content/uploads/2020/04/numgrade-layout.png" alt="numgrade layout" width="1288" height="1610" srcset="https://www.copier-coller.com/wp-content/uploads/2020/04/numgrade-layout.png 1288w, https://www.copier-coller.com/wp-content/uploads/2020/04/numgrade-layout-240x300.png 240w, https://www.copier-coller.com/wp-content/uploads/2020/04/numgrade-layout-819x1024.png 819w, https://www.copier-coller.com/wp-content/uploads/2020/04/numgrade-layout-80x100.png 80w, https://www.copier-coller.com/wp-content/uploads/2020/04/numgrade-layout-768x960.png 768w, https://www.copier-coller.com/wp-content/uploads/2020/04/numgrade-layout-1229x1536.png 1229w, https://www.copier-coller.com/wp-content/uploads/2020/04/numgrade-layout-624x780.png 624w" sizes="(max-width: 1288px) 100vw, 1288px" /></p>
<p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://www.copier-coller.com/creer-des-blocs-de-differentes-tailles-dans-vos-pages-darchives/">Créer des blocs de différentes tailles dans vos pages d&rsquo;archives</a> appeared first on <a rel="nofollow" href="https://www.copier-coller.com">Copier coller</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.copier-coller.com/creer-des-blocs-de-differentes-tailles-dans-vos-pages-darchives/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Préremplir les champs d&#8217;un formulaire à l&#8217;aide d&#8217;une chaîne de requête</title>
		<link>https://www.copier-coller.com/preremplir-les-champs-dun-formulaire-a-laide-dune-chaine-de-requete/</link>
					<comments>https://www.copier-coller.com/preremplir-les-champs-dun-formulaire-a-laide-dune-chaine-de-requete/#respond</comments>
		
		<dc:creator><![CDATA[copier coller]]></dc:creator>
		<pubDate>Fri, 10 Apr 2020 18:00:00 +0000</pubDate>
				<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://www.copier-coller.com/?p=6017</guid>

					<description><![CDATA[<p>Voici un tutoriel complet sur la possibilité de préremplir certains champs de formulaire. Nous allons ici utiliser : un custom post type Un widget un formulaire Ninja form des champs additionnels ACF Le scénario est le suivant. Nous sommes dans un article ou un custom post type « formation ». Il s&#8217;agit de cours informatiques, répartis par [...]</p>
<p>The post <a rel="nofollow" href="https://www.copier-coller.com/preremplir-les-champs-dun-formulaire-a-laide-dune-chaine-de-requete/">Préremplir les champs d&rsquo;un formulaire à l&rsquo;aide d&rsquo;une chaîne de requête</a> appeared first on <a rel="nofollow" href="https://www.copier-coller.com">Copier coller</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Comment personnaliser ses formulaires et les rendre dynamiques ?</h2>
<p>Voici un tutoriel complet sur la possibilité de préremplir certains champs de formulaire.</p>
<h3>Ce dont on a besoin</h3>
<p>Nous allons ici utiliser :</p>
<ul>
<li>un custom post type</li>
<li>Un widget</li>
<li>un formulaire Ninja form</li>
<li>des champs additionnels ACF</li>
</ul>
<h3>Le scénario</h3>
<p>Le scénario est le suivant. Nous sommes dans un article ou un custom post type « formation ». Il s&rsquo;agit de cours informatiques, répartis par catégories et par niveaux. Chaque post doit contenir des dates et des lieux spécifiques. Ces informations sont des « champ additionnels » ou « <em>cutom fields</em> » crées à l&rsquo;aide d&rsquo;ACF.</p>
<p>Dans la sidebar, on a un widget qui affiche les formations à venir. On les regroupe par ville puis par date de début et de fin.</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6022" src="https://www.copier-coller.com/wp-content/uploads/2020/03/widget-prochaines-sessions.png" alt="widget prochaines sessions" width="376" height="267" srcset="https://www.copier-coller.com/wp-content/uploads/2020/03/widget-prochaines-sessions.png 376w, https://www.copier-coller.com/wp-content/uploads/2020/03/widget-prochaines-sessions-300x213.png 300w" sizes="(max-width: 376px) 100vw, 376px" /></p>
<p>Ces dernières sont entourées d&rsquo;un lien dynamique qui doit renvoyer vers notre formulaire, en pré-remplissant certains champs. Par exemple, si je suis dans un article dont le titre est « python expert », et que je clique sur le premier lien « Orléans, du 18/05/2020 au 22/50/2020 », mon formulaire affichera alors en en-tête le titre et les informations de ville et de dates, comme ci-dessous.</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6025" src="https://www.copier-coller.com/wp-content/uploads/2020/03/ninja-form-dynamic-field1.png" alt="ninja form dynamic field" width="769" height="389" srcset="https://www.copier-coller.com/wp-content/uploads/2020/03/ninja-form-dynamic-field1.png 769w, https://www.copier-coller.com/wp-content/uploads/2020/03/ninja-form-dynamic-field1-300x152.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/03/ninja-form-dynamic-field1-624x316.png 624w" sizes="(max-width: 769px) 100vw, 769px" /></p>
<p>Lorsque l&rsquo;utilisateur valide le formulaire, on reçoit alors un mail indiquant entre autre les préférences de lieu et de date.</p>
<p>C&rsquo;est parti !</p>
<h3>Le custom post type</h3>
<p>Notre custom post formation a deux taxonomies, une pour les catégories de formation, une deuxième pour le niveau des formations. Je mets ici le code entier de mon CPT.</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">function cc_formation_cpt() {<br/>	/* Formation */<br/>	$labels = array(<br/>		&#039;name&#039;                =&gt; _x(&#039;Formations&#039;, &#039;Post Type General Name&#039;, &#039;text_domain&#039;),<br/>		&#039;singular_name&#039;       =&gt; _x(&#039;Formation&#039;, &#039;Post Type Singular Name&#039;, &#039;text_domain&#039;),<br/>		&#039;menu_name&#039;           =&gt; _x(&#039;Formations&#039;, &#039;text_domain&#039;),<br/>		&#039;name_admin_bar&#039;      =&gt; _x(&#039;Formations&#039;, &#039;text_domain&#039;),<br/>		&#039;all_items&#039;           =&gt; _x(&#039;Toutes les formations&#039;, &#039;text_domain&#039;),<br/>		&#039;add_new_item&#039;        =&gt; _x(&#039;Ajouter une nouvelle formation&#039;, &#039;text_domain&#039;),<br/>		&#039;add_new&#039;             =&gt; _x(&#039;Ajouter&#039;, &#039;text_domain&#039;),<br/>		&#039;new_item&#039;            =&gt; _x(&#039;Nouvelle formation&#039;, &#039;text_domain&#039; ),<br/>		&#039;edit_item&#039;           =&gt; _x(&#039;Editer la formation&#039;, &#039;text_domain&#039;),<br/>		&#039;update_item&#039;         =&gt; _x(&#039;Mettre à jour la formation&#039;, &#039;text_domain&#039;),<br/>		&#039;view_item&#039;           =&gt; _x(&#039;Voir la formation&#039;, &#039;text_domain&#039;),<br/>		&#039;search_items&#039;        =&gt; _x(&#039;Rechercher une formation&#039;, &#039;text_domain&#039;),<br/>		&#039;not_found&#039;           =&gt; _x(&#039;Aucune formation trouvée&#039;, &#039;text_domain&#039;),<br/>		&#039;not_found_in_trash&#039;  =&gt; _x(&#039;Aucune formation trouvée dans la corbeille&#039;, &#039;text_domain&#039;),<br/>	);<br/>	<br/>	$args = array(<br/>		&#039;label&#039;               =&gt; _x(&#039;Formation&#039;, &#039;text_domain&#039;),<br/>		&#039;description&#039;         =&gt; _x(&#039;Formations&#039;, &#039;text_domain&#039;),<br/>		&#039;labels&#039;              =&gt; $labels,<br/>		&#039;supports&#039;            =&gt; array(&#039;title&#039;, &#039;editor&#039;, &#039;thumbnail&#039;, &#039;comments&#039;, &#039;revisions&#039;, &#039;custom-fields&#039;),<br/>		&#039;hierarchical&#039;        =&gt; false,<br/>		&#039;public&#039;              =&gt; true,<br/>		&#039;show_ui&#039;             =&gt; true,<br/>		&#039;show_in_menu&#039;        =&gt; true,<br/>		&#039;menu_position&#039;       =&gt; 5,<br/>		&#039;menu_icon&#039;           =&gt; &#039;dashicons-admin-home&#039;,<br/>		&#039;show_in_admin_bar&#039;   =&gt; true,<br/>		&#039;show_in_nav_menus&#039;   =&gt; true,<br/>		&#039;can_export&#039;          =&gt; true,<br/>		&#039;has_archive&#039;         =&gt; false,<br/>		&#039;exclude_from_search&#039; =&gt; false,<br/>		&#039;publicly_queryable&#039;  =&gt; true,<br/>		&#039;query_var&#039;           =&gt; true,<br/>		&#039;rewrite&#039;             =&gt;  array( &#039;slug&#039; =&gt; &#039;toutes-nos-formations&#039; ),<br/>		&#039;capability_type&#039;     =&gt; &#039;post&#039;,<br/>		&#039;show_in_rest&#039;			=&gt;&#039;true&#039;,<br/>	);<br/>	register_post_type(&#039;formation&#039;, $args);	<br/>}<br/>add_action(&#039;init&#039;, &#039;cc_formation_cpt&#039;, 10);<br/><br/><br/><br/>function cc_formation_category_taxonomies() {<br/><br/>	$labels_cat_formation = array(<br/>		&#039;name&#039;                       =&gt; _x( &#039;Catégories de la formation&#039;, &#039;taxonomy general name&#039;),<br/>		&#039;singular_name&#039;              =&gt; _x( &#039;Catégories de la formation&#039;, &#039;taxonomy singular name&#039;),<br/>		&#039;search_items&#039;               =&gt; __( &#039;Rechercher une catégorie&#039;),<br/>		&#039;popular_items&#039;              =&gt; __( &#039;Catégories populaires&#039;),<br/>		&#039;all_items&#039;                  =&gt; __( &#039;Toutes les catégories&#039;),<br/>		&#039;edit_item&#039;                  =&gt; __( &#039;Editer une catégorie&#039;),<br/>		&#039;update_item&#039;                =&gt; __( &#039;Mettre à jour une catégorie&#039;),<br/>		&#039;add_new_item&#039;               =&gt; __( &#039;Ajouter une nouvelle catégorie&#039;),<br/>		&#039;new_item_name&#039;              =&gt; __( &#039;Nom de la nouvelle catégorie&#039;),<br/>		&#039;add_or_remove_items&#039;        =&gt; __( &#039;Ajouter ou supprimer une catégorie&#039;),<br/>		&#039;choose_from_most_used&#039;      =&gt; __( &#039;Choisir parmi les catégories les plus utilisées&#039;),<br/>		&#039;not_found&#039;                  =&gt; __( &#039;Pas de catégories trouvée&#039;),<br/>		&#039;menu_name&#039;                  =&gt; __( &#039;Catégorie de formation&#039;),<br/>	);<br/><br/>	$args_cat_formation = array(<br/>		&#039;hierarchical&#039;          =&gt; true,<br/>		&#039;labels&#039;                =&gt; $labels_cat_formation,<br/>		&#039;show_ui&#039;               =&gt; true,<br/>		&#039;show_in_rest&#039;			=&gt; true,<br/>		&#039;show_admin_column&#039;     =&gt; true,<br/>		&#039;query_var&#039;             =&gt; true,<br/>		&#039;rewrite&#039;               =&gt; array( &#039;slug&#039; =&gt; &#039;categories-formations&#039; ),<br/>	);<br/><br/>	register_taxonomy( &#039;categories-formations&#039;, &#039;formation&#039;, $args_cat_formation );<br/>}<br/>add_action( &#039;init&#039;, &#039;cc_formation_category_taxonomies&#039;, 0 );<br/><br/>function cc_formation_level_taxonomies() {<br/><br/>	$labels_level_formation = array(<br/>		&#039;name&#039;                       =&gt; _x( &#039;Niveaux de la formation&#039;, &#039;taxonomy general name&#039;),<br/>		&#039;singular_name&#039;              =&gt; _x( &#039;Niveau de la formation&#039;, &#039;taxonomy singular name&#039;),<br/>		&#039;search_items&#039;               =&gt; __( &#039;Rechercher un niveau&#039;),<br/>		&#039;popular_items&#039;              =&gt; __( &#039;Niveaux populaires&#039;),<br/>		&#039;all_items&#039;                  =&gt; __( &#039;Tous les Niveaux&#039;),<br/>		&#039;edit_item&#039;                  =&gt; __( &#039;Editer un niveau&#039;),<br/>		&#039;update_item&#039;                =&gt; __( &#039;Mettre à jour un niveau&#039;),<br/>		&#039;add_new_item&#039;               =&gt; __( &#039;Ajouter un nouveau niveau&#039;),<br/>		&#039;new_item_name&#039;              =&gt; __( &#039;Nom de le nouveau niveau&#039;),<br/>		&#039;add_or_remove_items&#039;        =&gt; __( &#039;Ajouter ou supprimer un niveau&#039;),<br/>		&#039;choose_from_most_used&#039;      =&gt; __( &#039;Choisir parmi les nivexau les plus utilisées&#039;),<br/>		&#039;not_found&#039;                  =&gt; __( &#039;Pas de niveau trouvé&#039;),<br/>		&#039;menu_name&#039;                  =&gt; __( &#039;Niveau de formation&#039;),<br/>	);<br/><br/>	$args_level_formation = array(<br/>	<br/>		&#039;hierarchical&#039;          =&gt; true,<br/>		&#039;labels&#039;                =&gt; $labels_level_formation,<br/>		&#039;show_ui&#039;               =&gt; true,<br/>		&#039;show_in_rest&#039;			=&gt; true,<br/>		&#039;show_admin_column&#039;     =&gt; true,<br/>		&#039;query_var&#039;             =&gt; true,<br/>		&#039;rewrite&#039;               =&gt; array( &#039;slug&#039; =&gt; &#039;niveau-formations&#039; ),<br/>	);<br/><br/>	register_taxonomy( &#039;niveau-formations&#039;, &#039;formation&#039;, $args_level_formation );<br/>}<br/>add_action( &#039;init&#039;, &#039;cc_formation_level_taxonomies&#039;, 0 );</code></pre> <div class="code-embed-infos"> </div> </div>
<h3>Les champs ACF</h3>
<p>Depuis le backoffice et les options d&rsquo;Acf, je rajoute mes trois champs <em>ville</em>, <em>date de début</em> et <em>date de fin.</em></p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6018" src="https://www.copier-coller.com/wp-content/uploads/2020/03/acf-fields.png" alt="acf fields" width="1234" height="171" srcset="https://www.copier-coller.com/wp-content/uploads/2020/03/acf-fields.png 1234w, https://www.copier-coller.com/wp-content/uploads/2020/03/acf-fields-300x42.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/03/acf-fields-1024x142.png 1024w, https://www.copier-coller.com/wp-content/uploads/2020/03/acf-fields-768x106.png 768w, https://www.copier-coller.com/wp-content/uploads/2020/03/acf-fields-624x86.png 624w" sizes="(max-width: 1234px) 100vw, 1234px" /></p>
<h4>Champ ville ou location</h4>
<p>Pour le champ « <em>ville »</em>, je choisi un champ select et renseigne les différentes options.</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6020" src="https://www.copier-coller.com/wp-content/uploads/2020/03/champ-acf-ville.png" alt="champ acf ville" width="976" height="537" srcset="https://www.copier-coller.com/wp-content/uploads/2020/03/champ-acf-ville.png 976w, https://www.copier-coller.com/wp-content/uploads/2020/03/champ-acf-ville-300x165.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/03/champ-acf-ville-768x423.png 768w, https://www.copier-coller.com/wp-content/uploads/2020/03/champ-acf-ville-624x343.png 624w" sizes="(max-width: 976px) 100vw, 976px" /></p>
<h4>Champ date</h4>
<p>Pour le champ « <em>date_de_debut</em> » et « <em>date_de_fin</em>« , je choisir le type « date » et son format.</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6019" src="https://www.copier-coller.com/wp-content/uploads/2020/03/champ-date-acf.png" alt="champ date acf" width="1226" height="759" srcset="https://www.copier-coller.com/wp-content/uploads/2020/03/champ-date-acf.png 1226w, https://www.copier-coller.com/wp-content/uploads/2020/03/champ-date-acf-300x186.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/03/champ-date-acf-1024x634.png 1024w, https://www.copier-coller.com/wp-content/uploads/2020/03/champ-date-acf-768x475.png 768w, https://www.copier-coller.com/wp-content/uploads/2020/03/champ-date-acf-624x386.png 624w" sizes="(max-width: 1226px) 100vw, 1226px" /></p>
<p>Enfin, je précise les conditions d&rsquo;affichage : ici le « <em>type de publication</em> » doit être égal à « Formation » (le nom de mon custom post type.)</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6021" src="https://www.copier-coller.com/wp-content/uploads/2020/03/condition-acf.png" alt="condition acf" width="1226" height="191" srcset="https://www.copier-coller.com/wp-content/uploads/2020/03/condition-acf.png 1226w, https://www.copier-coller.com/wp-content/uploads/2020/03/condition-acf-300x47.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/03/condition-acf-1024x160.png 1024w, https://www.copier-coller.com/wp-content/uploads/2020/03/condition-acf-768x120.png 768w, https://www.copier-coller.com/wp-content/uploads/2020/03/condition-acf-624x97.png 624w" sizes="(max-width: 1226px) 100vw, 1226px" /></p>
<p>Dans mon projet, je n&rsquo;affiche pas ces champs dans le fichier single-formation. Ces articles ne doivent pas contenir de dates ni de lieu attitrés. Mais ces informations sont bien enregistrées en base de donnée au moment de l&rsquo;édition du CPT. On va donc pouvoir les récupérer et les afficher ailleurs.</p>
<h3>Le widget des « formations à venir »</h3>
<p>Voici le code complet de mon widget.</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">	class Cc_Upcoming_Events extends WP_Widget {<br/>	 		function __construct() {<br/>	 		parent::__construct(<br/>					&#039;cc_upcoming_events&#039;, // Base ID<br/>					__( &#039;Cc Upcoming Events&#039;, &#039;text_domain&#039; ), // Name<br/>					array( &#039;description&#039; =&gt; __( &#039;Shows Formations dates&#039;, &#039;text_domain&#039; ), ) // Args<br/>			);<br/>		}<br/><br/>	 <br/>	 <br/>	public function form( $instance ) {<br/>		   $tax_id = &#039;&#039;;<br/>		    if( !empty( $instance[&#039;tax_id&#039;] ) ) {<br/>		    	 $tax_id = absint( $instance[&#039;tax_id&#039;] ) ;<br/>		 	}<br/>		 	  $niveau_id = &#039;&#039;;<br/>		    if( !empty( $instance[&#039;niveau_id&#039;] ) ) {<br/>		    	 $niveau_id = absint( $instance[&#039;niveau_id&#039;] ) ;<br/>		 	}<br/>		 $widget_defaults = array(<br/>		    &#039;title&#039;         =&gt;   &#039;Upcoming Events&#039;,<br/>		    &#039;number_events&#039; =&gt;   5<br/>		);<br/>	 <br/>		$instance  = wp_parse_args( (array) $instance, $widget_defaults );?&gt;<br/>		&lt;p&gt;<br/>		    &lt;label for=&quot;&lt;?php echo $this-&gt;get_field_id( &#039;title&#039; ); ?&gt;&quot;&gt;&lt;?php _e( &#039;Title&#039;, &#039;text_domain&#039; ); ?&gt;&lt;/label&gt;<br/>		    &lt;input type=&quot;text&quot; id=&quot;&lt;?php echo $this-&gt;get_field_id( &#039;title&#039; ); ?&gt;&quot; name=&quot;&lt;?php echo $this-&gt;get_field_name( &#039;title&#039; ); ?&gt;&quot; class=&quot;widefat&quot; value=&quot;&lt;?php echo esc_attr( $instance[&#039;title&#039;] ); ?&gt;&quot;&gt;<br/>		&lt;/p&gt;<br/>		&lt;p&gt;<br/>		    &lt;label for=&quot;&lt;?php echo $this-&gt;get_field_id( &#039;number_events&#039; ); ?&gt;&quot;&gt;&lt;?php _e( &#039;Number of events to show&#039;, &#039;text_domain&#039; ); ?&gt;&lt;/label&gt;<br/>		    &lt;select id=&quot;&lt;?php echo $this-&gt;get_field_id( &#039;number_events&#039; ); ?&gt;&quot; name=&quot;&lt;?php echo $this-&gt;get_field_name( &#039;number_events&#039; ); ?&gt;&quot; class=&quot;widefat&quot;&gt;<br/>		        &lt;?php for ( $i = 1; $i &lt;= 10; $i++ ): ?&gt;<br/>		            &lt;option value=&quot;&lt;?php echo $i; ?&gt;&quot; &lt;?php selected( $i, $instance[&#039;number_events&#039;], true ); ?&gt;&gt;&lt;?php echo $i; ?&gt;&lt;/option&gt;<br/>		        &lt;?php endfor; ?&gt;<br/>		    &lt;/select&gt;<br/>		&lt;/p&gt;<br/>		  &lt;p&gt;<br/>	            &lt;label for=&quot;&lt;?php echo $this-&gt;get_field_id(&#039;tax_id&#039;); ?&gt;&quot;&gt;&lt;?php _e( &#039;Taxonomy Name:&#039; )?&gt;&lt;/label&gt;<br/>	            &lt;select id=&quot;&lt;?php echo $this-&gt;get_field_id(&#039;tax_id&#039;); ?&gt;&quot; name=&quot;&lt;?php echo $this-&gt;get_field_name(&#039;tax_id&#039;); ?&gt;&quot;&gt;<br/>	                     &lt;?php <br/>	               $custom_terms = get_terms(&#039;categories-formations&#039;);<br/><br/>					foreach($custom_terms as $custom_term) {<br/>	                    $selected = ( $custom_term-&gt;term_id == esc_attr( $tax_id ) ) ? &#039; selected = &quot;selected&quot; &#039; : &#039;&#039;;<br/>	                    $option = &#039;&lt;option &#039;.$selected .&#039;value=&quot;&#039; . $custom_term-&gt;term_id;<br/>	                    $option = $option .&#039;&quot;&gt;&#039;;<br/>	                    $option = $option .$custom_term-&gt;name;<br/>	                    $option = $option .&#039;&lt;/option&gt;&#039;;<br/>	                    echo $option;<br/>	                }<br/>	                ?&gt;<br/>	            &lt;/select&gt;<br/>	        <br/>	        &lt;/p&gt;<br/><br/>	        &lt;p&gt;<br/>	            &lt;label for=&quot;&lt;?php echo $this-&gt;get_field_id(&#039;niveau_id&#039;); ?&gt;&quot;&gt;&lt;?php _e( &#039;Level Name:&#039; )?&gt;&lt;/label&gt;<br/>	            &lt;select id=&quot;&lt;?php echo $this-&gt;get_field_id(&#039;niveau_id&#039;); ?&gt;&quot; name=&quot;&lt;?php echo $this-&gt;get_field_name(&#039;niveau_id&#039;); ?&gt;&quot;&gt;<br/>	                     &lt;?php <br/>	               $custom_terms = get_terms(&#039;niveau-formations&#039;);<br/><br/>					foreach($custom_terms as $custom_term) {<br/>	                    $selected = ( $custom_term-&gt;term_id == esc_attr( $niveau_id ) ) ? &#039; selected = &quot;selected&quot; &#039; : &#039;&#039;;<br/>	                    $option = &#039;&lt;option &#039;.$selected .&#039;value=&quot;&#039; . $custom_term-&gt;term_id;<br/>	                    $option = $option .&#039;&quot;&gt;&#039;;<br/>	                    $option = $option .$custom_term-&gt;name;<br/>	                    $option = $option .&#039;&lt;/option&gt;&#039;;<br/>	                    echo $option;<br/>	                }<br/>	                ?&gt;<br/>	            &lt;/select&gt;<br/>	        <br/>	        &lt;/p&gt;<br/>	&lt;?php<br/>	}<br/>	 <br/>	 <br/>	   <br/>	public function update( $new_instance, $old_instance ) {<br/>	    $instance = $old_instance;<br/>	 <br/>	    $instance[&#039;title&#039;] = $new_instance[&#039;title&#039;];<br/>	    $instance[&#039;number_events&#039;] = $new_instance[&#039;number_events&#039;];<br/>		$instance[&#039;tax_id&#039;] = ( ! empty( $new_instance[&#039;tax_id&#039;] ) ) ? strip_tags( $new_instance[&#039;tax_id&#039;] ) : &#039;&#039;;<br/>		$instance[&#039;niveau_id&#039;] = ( ! empty( $new_instance[&#039;niveau_id&#039;] ) ) ? strip_tags( $new_instance[&#039;niveau_id&#039;] ) : &#039;&#039;;<br/>	    return $instance;<br/>	}<br/>	    <br/>	 <br/>	 <br/>	public function widget( $args, $instance ) {<br/>		echo $args[&#039;before_widget&#039;];<br/>	  	extract( $args );<br/>	    $title = apply_filters( &#039;widget_title&#039;, $instance[&#039;title&#039;] );<br/>	    $tax_id     = absint( $instance[&#039;tax_id&#039;] ) ;<br/>		$niveau_id     = absint( $instance[&#039;niveau_id&#039;] ) ;<br/>	 	$args = array(<br/>		    &#039;post_type&#039; =&gt; &#039;formation&#039;,<br/>            &#039;posts_per_page&#039;    =&gt; $instance[&#039;number_events&#039;],<br/>            &#039;tax_query&#039; =&gt; array(<br/>            	&#039;relation&#039; =&gt; &#039;AND&#039;,<br/>                array(<br/>                    &#039;taxonomy&#039; =&gt; &#039;categories-formations&#039;,<br/>                    &#039;field&#039; =&gt; &#039;term_id&#039;,<br/>                    &#039;terms&#039; =&gt; $tax_id,<br/>                ),<br/>                 array(<br/>			        &#039;taxonomy&#039; =&gt; &#039;niveau-formations&#039;,<br/>			        &#039;field&#039;    =&gt; &#039;term_id&#039;,<br/>			        &#039;terms&#039;    =&gt;  $niveau_id,<br/>			    ),<br/>            ),<br/>           <br/>            );<br/><br/>		$upcoming_events = new WP_Query($args);<br/>		<br/>		if ( $title ) {<br/>		    echo $before_title . $title . $after_title;<br/>		}<br/>		// vars<br/>	?&gt;						 <br/>		<br/>		    &lt;?php  <br/>		   <br/>			$title = get_the_title();<br/>				// First, group the posts by the city.<br/>			$groups = array();<br/>			foreach ( $upcoming_events-&gt;posts as $i =&gt; $p ) {<br/>			    $city = get_field( &#039;ville&#039;, $p-&gt;ID );<br/><br/>			    if ( ! isset( $groups[ $city ] ) ) {<br/>			        $groups[ $city ] = array();<br/>			    }<br/>			    $groups[ $city ][] =&amp; $upcoming_events-&gt;posts[ $i ];<br/>			}<br/><br/>			// Optional, sort the city names.<br/>			ksort( $groups, SORT_FLAG_CASE );<br/><br/>			// Then display the posts.<br/>			if ( ! empty( $groups ) ) {<br/>			    echo &#039;&lt;div class=&quot;event_entries&quot;&gt;&#039;;<br/>			    foreach ( $groups as $city =&gt; $posts ) {<br/>			        if ( ! empty( $posts ) ) {<br/>			            // Display city name.<br/>			            echo &#039;&lt;h3&gt;&#039; . $city . &#039;&lt;/h3&gt;&#039;;<br/><br/>			            // Display posts in that city.<br/>			            echo &#039;&lt;ul&gt;&#039;;<br/>			            foreach ( $posts as $post ) {<br/>			                $event_start_date = get_field( &#039;date_de_debut&#039;, $post-&gt;ID );<br/>			                $event_end_date   = get_field( &#039;date_de_fin&#039;, $post-&gt;ID );<br/>			                <br/>			                echo &#039;&lt;li&gt;&lt;a href=&quot;http://localhost/monsite/inscription/?titre=&#039;. $title . &#039;&amp;ville=&#039;.  $city .&#039;&amp;date_de_debut=&#039; .  $event_start_date .&#039;&amp;date_de_fin=&#039; .  $event_end_date .&#039;&amp;niveau=&#039; . $niveau_id .&#039;&amp;categorie=&#039; . $tax_id  . &#039;&quot;&gt; Du &#039; . $event_start_date . &#039; au &#039; . $event_end_date . &#039;&lt;/a&gt;&lt;/li&gt;&#039;;				<br/>			            }<br/>			            echo &#039;&lt;/ul&gt;&#039;;<br/>			        }<br/>			    }<br/>			    echo &#039;&lt;/div&gt;&#039;; // close .event_entries<br/>			}<br/>		 ?&gt;<br/>		<br/>		 <br/>		&lt;?php<br/>		<br/>		 <br/>		echo $after_widget;<br/>	}<br/>}</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Dans la fonction « <em>form</em>« , on a plusieurs champs select : un pour le nombre de post à afficher, un second pour ma taxonomie « catégorie », un dernier pour ma taxonomie « niveau ».</p>
<p>Pour pouvoir boucler sur notre CPT en fonction de ces deux taxonomies et des <em>terms</em> sélectionnés par l&rsquo;utilisateur, on va créer la boucle avec une « <a href="https://developer.wordpress.org/reference/classes/wp_query/"><em>multiple tax_query</em></a> » comme expliqué dans le codex</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">	$args = array(<br/>		    &#039;post_type&#039; =&gt; &#039;formation&#039;,<br/>            &#039;posts_per_page&#039;    =&gt; $instance[&#039;number_events&#039;],<br/>            &#039;tax_query&#039; =&gt; array(<br/>            	&#039;relation&#039; =&gt; &#039;AND&#039;,<br/>                array(<br/>                    &#039;taxonomy&#039; =&gt; &#039;categories-formations&#039;,<br/>                    &#039;field&#039; =&gt; &#039;term_id&#039;,<br/>                    &#039;terms&#039; =&gt; $tax_id,<br/>                ),<br/>                 array(<br/>			        &#039;taxonomy&#039; =&gt; &#039;niveau-formations&#039;,<br/>			        &#039;field&#039;    =&gt; &#039;term_id&#039;,<br/>			        &#039;terms&#039;    =&gt;  $niveau_id,<br/>			    ),<br/>            ),<br/>           <br/>            );<br/><br/>		$upcoming_events = new WP_Query($args);</code></pre> <div class="code-embed-infos"> </div> </div>
<p>Le reste du code nous permet, à travers des boucles imbriquées, d&rsquo;afficher les custom post type, en les regroupant par ville. On a ainsi une répartition avec la ville en titre, et tous les CPT enregistrés avec la même ville dans une liste juste en dessous.</p>
<h3>Le lien dynamique et notre query string</h3>
<p>Dans le dernier <em>foreach</em>, on récupère nos custom field « <em>date_de_debut</em> » et « <em>date_de_fin</em>« , et on construit le lien avec notre requête dynamique. Je récupère aussi le titre de l&rsquo;article avec $title = get_the_title(); ,  et les champs ACF.</p>
<div class="code-embed-wrapper"> <pre class="language-php code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-php code-embed-code">  foreach ( $posts as $post ) {<br/>			                $event_start_date = get_field( &#039;date_de_debut&#039;, $post-&gt;ID );<br/>			                $event_end_date   = get_field( &#039;date_de_fin&#039;, $post-&gt;ID );<br/>			                <br/>			                echo &#039;&lt;li&gt;&lt;a href=&quot;http://localhost/monsite/inscription/?titre=&#039;. $title . &#039;&amp;ville=&#039;.  $city .&#039;&amp;date_de_debut=&#039; .  $event_start_date .&#039;&amp;date_de_fin=&#039; .  $event_end_date .&#039;&amp;niveau=&#039; . $niveau_id .&#039;&amp;categorie=&#039; . $tax_id  . &#039;&quot;&gt; Du &#039; . $event_start_date . &#039; au &#039; . $event_end_date . &#039;&lt;/a&gt;&lt;/li&gt;&#039;;				<br/>			            }</code></pre> <div class="code-embed-infos"> </div> </div>
<p>&nbsp;</p>
<p>Au besoin je récupère aussi les taxonomies choisies dans les champs select du widget.</p>
<h3>Le formulaire : Ninja Form</h3>
<p>Pour mon formulaire, j’utilise <a href="https://ninjaforms.com/">Ninja Form</a>, mais d&rsquo;autres proposent les mêmes fonctionnalités : <a href="https://wpforms.com/">wp_form</a>, <a href="https://www.gravityforms.com/">gravity form</a> etc. C&rsquo;est aussi possible avec Contact form 7 et le plugin <a href="https://wordpress.org/plugins/contact-form-7-dynamic-text-extension/">contact form 7 dynamic text extension</a>.</p>
<p>Avec la version gratuite de Ninja Form, construisez votre formulaire. Un tuto explique très bien comment créer et récupérer les données d&rsquo;un lien dynamique dans Ninja Form.</p>
<h4>Créer deux champs additionnels pour mes « query string »</h4>
<p>Pour suivre mon exemple, je vais donc devoir créer deux champs additionnels : un pour afficher le titre du CPT de provenance, l&rsquo;autre pour afficher les valeurs de mes champs ACF.</p>
<p>Je crée donc deux « <em>lignes de texte</em>« .</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6028" src="https://www.copier-coller.com/wp-content/uploads/2020/03/query-ninja-form-fields.png" alt="query ninja form fields" width="682" height="257" srcset="https://www.copier-coller.com/wp-content/uploads/2020/03/query-ninja-form-fields.png 682w, https://www.copier-coller.com/wp-content/uploads/2020/03/query-ninja-form-fields-300x113.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/03/query-ninja-form-fields-624x235.png 624w" sizes="(max-width: 682px) 100vw, 682px" /></p>
<h5>Querystring pour le titre du CPT</h5>
<p>On efface les libellés, et dans les restrictions, on désactive la saisie. Si les restrictions ne s&rsquo;affichent pas, il faut retourner dans les options du plugin et activer le <strong>mode « développeur ».</strong></p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6026" src="https://www.copier-coller.com/wp-content/uploads/2020/03/titre-ninja-disable-field.png" alt="titre ninja disable field" width="848" height="318" srcset="https://www.copier-coller.com/wp-content/uploads/2020/03/titre-ninja-disable-field.png 848w, https://www.copier-coller.com/wp-content/uploads/2020/03/titre-ninja-disable-field-300x113.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/03/titre-ninja-disable-field-768x288.png 768w, https://www.copier-coller.com/wp-content/uploads/2020/03/titre-ninja-disable-field-624x234.png 624w" sizes="(max-width: 848px) 100vw, 848px" /></p>
<p>Dans l&rsquo;affichage, je définis comme valeur par défaut ma première query string : {querystring:titre}. Le champ va donc récupérer ici ma variable titre insérée plus tôt dans mon lien.</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6027" src="https://www.copier-coller.com/wp-content/uploads/2020/03/titre-ninja-form.png" alt="" width="848" height="571" srcset="https://www.copier-coller.com/wp-content/uploads/2020/03/titre-ninja-form.png 848w, https://www.copier-coller.com/wp-content/uploads/2020/03/titre-ninja-form-300x202.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/03/titre-ninja-form-768x517.png 768w, https://www.copier-coller.com/wp-content/uploads/2020/03/titre-ninja-form-624x420.png 624w" sizes="(max-width: 848px) 100vw, 848px" /></p>
<p>Si je suis dans une formation dont le titre est « python expert » par exemple, je le retrouverai donc dans mon formulaire. On peut ensuite le styliser, comme ci-dessous.</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6025" src="https://www.copier-coller.com/wp-content/uploads/2020/03/ninja-form-dynamic-field1.png" alt="ninja form dynamic field" width="769" height="389" srcset="https://www.copier-coller.com/wp-content/uploads/2020/03/ninja-form-dynamic-field1.png 769w, https://www.copier-coller.com/wp-content/uploads/2020/03/ninja-form-dynamic-field1-300x152.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/03/ninja-form-dynamic-field1-624x316.png 624w" sizes="(max-width: 769px) 100vw, 769px" /></p>
<p>Dans les « <em>noms de classe personnalisées</em>« , j&rsquo;ajoute mes classes qui vont justement me servir à styliser mon titre : enlever les bordures, changer la taille de police, modifier les marges etc.</p>
<h5>Querystring pour la ville et les dates</h5>
<p>Mon deuxième champ va me permettre de récupérer les informations de ville et de dates envoyés depuis mon widget.</p>
<p><img decoding="async" loading="lazy" class="alignnone size-full wp-image-6029" src="https://www.copier-coller.com/wp-content/uploads/2020/03/ninja-form-hidden-input-2.png" alt="ninja form hidden input 2" width="840" height="347" srcset="https://www.copier-coller.com/wp-content/uploads/2020/03/ninja-form-hidden-input-2.png 840w, https://www.copier-coller.com/wp-content/uploads/2020/03/ninja-form-hidden-input-2-300x124.png 300w, https://www.copier-coller.com/wp-content/uploads/2020/03/ninja-form-hidden-input-2-768x317.png 768w, https://www.copier-coller.com/wp-content/uploads/2020/03/ninja-form-hidden-input-2-624x258.png 624w" sizes="(max-width: 840px) 100vw, 840px" /></p>
<p>Ici aussi j&rsquo;efface le libellé, je désactive la saisie. Je personnalise la valeur de ma chaîne de requête avec du texte additionnel. Je nomme mes tags exactement de la même manière que dans mon lien dynamique : <em>{querystring:<strong>date_de_debut</strong>}, {querystring:<strong>date_de_fin</strong>}</em> et <em>{querystring:<strong>ville</strong>}. </em>:</p>
<p>&amp;<strong>ville</strong>=&rsquo;. $city .&rsquo;&amp;<strong>date_de_debut</strong>=&rsquo; . $event_start_date .&rsquo;&amp;<strong>date_de_fin</strong>=&rsquo; . $event_end_date</p>
<h3>Un autre affichage</h3>
<p>Si pour une raison quelconque l&rsquo;utilisateur peut accéder à la page du formulaire sans passer par le widget, il se peut que vous ayez envie de cacher l&rsquo;en-tête. Sinon on verra une mention « Session du   au », ce qui pourra paraître bizarre.</p>
<p>Dans ce cas, on peut tout à fait ne laisser que <em>{querystring:<strong>date_de_debut</strong>}, {querystring:<strong>date_de_fin</strong>}</em> <em>{querystring:<strong>ville</strong>}. </em>dans le champ « valeur par défaut » de ninja form et ajouter ces informations dans le html directement</p>
<p>&amp;<strong>ville</strong>= à &lsquo;. $city .&rsquo;&amp;<strong>date_de_debut</strong>= Session du&rsquo; . $event_start_date .&rsquo;&amp;<strong>date_de_fin</strong>= au &lsquo; . $event_end_date</p>
<h3>Tester !!</h3>
<p>Maintenant, au clic sur une des dates de mon widget, je suis redirigé vers mon formulaire, c&rsquo;est la partie « <em>http://localhost/monsite/inscription/</em> » de mon lien. Si vous avez bien fait les choses, vous verrez dans l&rsquo;url vos query après le « ? » et les valeurs correspondantes à chaque query string.</p>
<p>N&rsquo;hésitez pas, si vous avez des idées d&rsquo;amélioration ou des corrections à apporter à ce tuto !</p>
<p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://www.copier-coller.com/preremplir-les-champs-dun-formulaire-a-laide-dune-chaine-de-requete/">Préremplir les champs d&rsquo;un formulaire à l&rsquo;aide d&rsquo;une chaîne de requête</a> appeared first on <a rel="nofollow" href="https://www.copier-coller.com">Copier coller</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.copier-coller.com/preremplir-les-champs-dun-formulaire-a-laide-dune-chaine-de-requete/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
