Home » wordpress » Acf Google Map et catégories multiples
Acf Google Map et catégories multiples
Acf Google Map et catégories multiples
Après avoir vu comment créer des cartes google map avec ACF avec de multiples marqueurs, chaque marqueur étant un article, dans ce tuto nous allons voir comment créer des cartes pour nos catégories.Au clic sur une catégorie de la liste, on afficherait pour chaque catégorie une carte différente avec tous nos articles
Nous allons donc partir du même design que pour le précédent article.
Il y a dans le principe plusieurs manières de faire.On pourrait imaginer une liste de catégories, avec une seule carte,et on ferait apparaître/disparaître les marqueurs correspondants sur la carte, en fonction de la catégorie sélectionnée. on trouve de nombreux exemples, notamment sur fiddle .
On a d’autres exemples, ou au clic sur une catégorie de la liste , on fait apparaître/disparaître chaque carte correspondante.On a un bel exemple sur ce site .Ce dernier utilise ACF, et explique dans le forum d’ACF comment il parvient à ce résultat.
Dans l’exemple qui va suivre, j’utilise bootstrap et les tabs, et ACF(version gratuite).On va reprendre la même structure que pour les précédents tuto sur le sujet, et lister chaque étape
Télécharger ACF
Première étape bien sûr, il faut télécharger ACF.
Créer une clé API
Pour faire fonctionner google map dans ACF, il faut une clé API.la procédure peut faire peur au début, mais il suffit de suivre les étapes indiquées ici
Démarrer avec ACF
une fois le tout effectué, on peut aller dans les paramètres du plugin et créer nos custom fields.
Ici on va créer un simple champ additionnel que l’on va nommer google maps.Dans le backoffice, on clique sur l’onglet « ACF« , puis dans « groupe de champs« , on clique sur « ajouter« .
On donne au Titre du champ le nom de Google Maps, le Nom de champ se remplit tout seul, puis on selectionne google map en Type de champ.Le reste on n’y touche pas
Au bas de la page on définit l’emplacement de ce nouveau champ additionnel.Pour mon exemple, je vais partir sur les articles normaux.
La documentation ACF
Maintenant dans le code, pour que tout cela fonctionne il faut insérer certaines fonctions, selon les recommandations d’ACF.
Dans functions.php, insérer le code suivant
function my_acf_google_map_api( $api ){ $api['key'] = 'VotreCléAPI'; return $api; }
Ce code est nécessaire pour que la carte s’affiche.on reseigne ici sa clé API
Création des fonctions JS
On crée ensuite un fichier js, qu’on nomme par exemple, google.js.A l’intérieur on insère le code suivant:
(function($) {
/* * new_map * * This function will render a Google Map onto the selected jQuery element * * @type function * @date 8/11/2013 * @since 4.3.0 * * @param $el (jQuery element) * @return n/a */
function new_map( $el ) {
// var var $markers = $el.find('.marker');
// vars var args = { zoom : 16, center : new google.maps.LatLng(0, 0), mapTypeId : google.maps.MapTypeId.ROADMAP };
// create map var map = new google.maps.Map( $el[0], args);
// add a markers reference map.markers = [];
// add markers $markers.each(function(){
add_marker( $(this), map );
});
// center map center_map( map );
// return return map;
}
/* * add_marker * * This function will add a marker to the selected Google Map * * @type function * @date 8/11/2013 * @since 4.3.0 * * @param $marker (jQuery element) * @param map (Google Map object) * @return n/a */
function add_marker( $marker, map ) {
// var var latlng = new google.maps.LatLng( $marker.attr('data-lat'), $marker.attr('data-lng') );
// create marker var marker = new google.maps.Marker({ position : latlng, map : map });
// add to array map.markers.push( marker );
// if marker contains HTML, add it to an infoWindow if( $marker.html() ) { // create info window var infowindow = new google.maps.InfoWindow({ content : $marker.html() });
// show info window when marker is clicked google.maps.event.addListener(marker, 'click', function() {
infowindow.open( map, marker );
}); }
}
/* * center_map * * This function will center the map, showing all markers attached to this map * * @type function * @date 8/11/2013 * @since 4.3.0 * * @param map (Google Map object) * @return n/a */
function center_map( map ) {
// vars var bounds = new google.maps.LatLngBounds();
// loop through all markers and create bounds $.each( map.markers, function( i, marker ){
var latlng = new google.maps.LatLng( marker.position.lat(), marker.position.lng() );
bounds.extend( latlng );
});
// only 1 marker? if( map.markers.length == 1 ) { // set center of map map.setCenter( bounds.getCenter() ); map.setZoom( 16 ); } else { // fit to bounds map.fitBounds( bounds ); }
}
/* * document ready * * This function will render each map when the document is ready (page has loaded) * * @type function * @date 8/11/2013 * @since 5.0.0 * * @param n/a * @return n/a */ // global var var map = null;
$(document).ready(function(){
$('.acf-map').each(function(){
// create map map = new_map( $(this) );
});
});
})(jQuery);
Ces deux bouts de code sont ceux proposés par défaut dans la documentation d’ACF, il ne s »agit là que de simples copier-coller, le code est commenté pour mieux comprendre à quoi sert chaque fonction.
L’appel aux scripts
Il faut ensuite relier tout ca, en allant chercher les scripts de google et notre fichier js
Dans functions.php, à l’intérieur de votre fonction d’appel aux scripts, placez le code suivant
Ici aussi, il faut renseigner sa clé API à l’endroit indiqué.
Maintenant, dans chaque page d’édition d’article, je retrouve une nouvelle meta box avec ma carte google map.
ACF est tellement bien fait qu’il suffit juste de cliquer sur un endroit de la carte, ou d’insérer une adresse, pour que le marqueur se positionne et renvoie une adresse dans le champ.A l’enregistrement de l’article, la carte garde le marqueur en mémoire.
Il ne reste plus qu’à créer toute une série d’articles avec des adresses renseignées dans notre nouvelle metabox google map.On relie également chaque article à une catégorie
Création du custom field taxonomy
Maintenant, dans ACF on va :
créer un champ pour nos catégorie dans ACF (un champ taxonomy)
décider d’un emplacement ou l’on veut afficher ces catégories,
selectionner les catégories souhaitées dans la page.
Création du champ taxonomy
Dans un groupe de champ ou pas, on crée un nouveau champ « taxonomy »
Assigner un emplacement
On décide de l’emplacement de ce nouveau champ, ici je le place dans ma page d’accueil.Le but étant de créer une boucle qui me ramène les catégories selectionnée dans une section de ma page d’accueil
Selection des catégories
Dans l’édition de ma page d’accueil, dans mon nouveau champ acf, je sélectionne les catégories que je veux afficher dan ma boucle.La selection multiple me permet d’en selectionner plusieurs.
Tout ceci fait, on a maintenant l’essentiel. On a tous nos articles et leur carte, avec des positions latitude, longitude définies sur une carte, et on a nos catégories selectionnées.Il va donc falloir relier le tout.
Voici donc le code que j’insère dans une section de ma page home.php
$terms = get_field('categories_select');//je récupère mes catégories selectionnées if( $terms ): ?> <?php $i = 1; //ce compteur sert à incrémenter la classe active de bootstrap?> <?php foreach( $terms as $term ): //pour chacune de mes catégories?>
<?php $args = array( 'post_type' => 'post', //je recrée une deuxième boucle à l'intérieur pour me ramener cette fois tous les marqueurs de mes articles 'posts_per_page' => -1, 'category__in' => $term ); $the_query = new WP_Query($args); // j'insère ma boucle dans ma div acf map, la classe active est ajoutée à la premiere div,l'id change en fonction du nom de ma catégori ;?> <div class="acf-map tab-pane <?php if ($i == 1) echo 'active';?> fade in" id="<?php echo $term->slug ;?>"> <?php while ( $the_query->have_posts() ) : $the_query->the_post(); $location = get_field('google_maps');?>
<?php $terms = get_field('categories_select');//deuxième bloc, pour la liste, je recupère mes catégories if( $terms ): // je crée plus bas des fleches down et up pour sur lesquels on pourra cliquer pour faire défiler les catégories ;?> <div id="list"> <div class="down"> <span class="glyphicon glyphicon-chevron-down"></span> </div> <div id="listdata"> <?php // cette fois ma liste est composée de tabs bootstrap ;?> <ul clas="nav nav-tabs tabs-right" id="myModal"> <?php $i = 1; //j'incremente ici aussi pour la class active ?> <?php foreach( $terms as $term ):?> <li class="<?php if ($i == 1) echo 'active';?>"> <a href="#<?php echo $term->slug ;?>" class="linkage" data-toggle="tab"> <?php $category_image = get_field('categImg', $term); //ici je recupère l'image de ma catégorie que je recupère d'un custom field crée au préalable $image = $category_image['url']; ?> <img src="<?php echo $image ;?>" alt="" /> <h3><?php echo $term->name; ?></h3> </a> </li> <?php $i++; endforeach; ?> <?php wp_reset_postdata(); ?> </ul> </div> <div class="up"> <span class="glyphicon glyphicon-chevron-up"></span> </div> </div> <?php endif; ?> </div> </section>
j’ai commenté le code pour explication.J’utilise donc le code par défaut des tabs de bootstrap, à l’intérieur duquel j’ai placé mes boucles.
Problème de comptabilité
Maintenant, petit problème.Les tabs de bootstrap et google map ont un problème de compatibilité.En gros, chaque tab cachée est en display: none, ce qui signigie que google map est incapable dans une élément caché de définir une taille pour la carte.Si bien qu’au chargement de chaque carte, on se retrouve soit avec des cartes trop petites, tronquées, voir aucune carte.Il faut donc quelque part redimmensionner la carte lorsqu’elle s’affiche.
// fermer l'infowindow au clic sur une autre infowindow google.maps.event.addListener(marker, 'click', function() { if (typeof( window.infoopened ) != 'undefined') infoopened.close(); infowindow.open(map,marker); infoopened = infowindow;
});
}
}
on remplace la précédente fonction add_marker par celle ci.A l’intérieur de la fonction proposée par bootstrap :
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
})
on va donc rajouter une fonction de redimmensionnement, on va recentrer la carte en reprenant la variable latlng créee plus haut dans le code,et on va rezoomer.Dans mon exemple, sans le zoom, la carte reste tronquée..
Voilà donc le début d’une piste pour afficher des catétorie et des cartes contenant les articles liés.