Structure de site wordpress : spliter the_content

Comment casser la structure d’un site wordpress :

Une structure figée

Dans ce petit mémo, le but est de parvenir à créer un template wordpress original, en essayant de casser la structure habituelle des pages, et sortir des éléments du contenu affiché par la fonction the_content().

Je m’explique: quand on prend un thème par défaut worpdress, parmi les twenty-machin, on voit que la structure reste figée sur l’ensemble du site.

Voici la structure d’un thème wordpress par défaut, de laquelle on peut partir pour développer son propre thème.

<html>
<head>
<title></title>
</head>
<body>
<div id="page" class="hfeed site">
<header id="masthead" class="site-header" role="banner">
</header>
<div id="main" class="wrapper">
<div id="primary" class="site-content">
<div id="content" role="main">
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
..
<?php get_template_part('content', get_post_format()); ?>
..
</article>
</div>
</div>
<div id="secondary" class="widget-area" role="complementary">
</div>
</div>
</div>
</body>
</html>

Quand on y regarde de près, c’est la structure d’une page, d’une catégorie, de l’index, finalement…de tout le site.

Lorsqu’on se trouve sur une page, une catégorie, ou un article, finalement quelque soit la page qu’on inspecte, on voit qu’on a toujours la même structure « englobante »:

<html>
<head>
<title></title>
</head>
<body>
<div id="page" class="hfeed site">
<header id="masthead" class="site-header" role="banner">
</header>
<div id="main" class="wrapper">
<div id="primary" class="site-content">
<div id="content" role="main">
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>

Et c’est grace à la fonction  :

<?php get_template_part('content', get_post_format()); ?> 

qu’on affiche le contenu approprié en fonction du post format choisi. C’est donc le css appliqué à partir des <article></article> qui va modifier le rendu. Mais le cadre lui, reste le même.En gros..

mockupweb1_3

Comme on le voit sur cette image, on est vite bloqué si on souhaite créer, dans un type de contenu particulier( les post-format video ou post-format gallery par exemple, ou dans un custom post, ) un slider géant ou une vidéo , ou encore l’image à la une prenant toute la page puis en dessous le reste de l’article et la sidebar par exemple…En l’état, c’est impossible.

Comment casser the_content() ?

  • Les div « primary » et div « content » qu’on retrouve dans les pages single ou dans les pages, ont une taille définie.
  • On a la sidebar sur le coté,
  • Le logo qui prend pas mal de place…

Alors comment repenser les espaces vides pour arriver à cette structure?

mockupweb1

Casser la structure du thème : une fausse bonne idée

Une des solutions consiste déjà à supprimer de la page single les deux div englobantes primary et content.

<html>
<head>
<title></title>
</head>
<body>
<div id="page" class="hfeed site">
<header id="masthead" class="site-header" role="banner">
</header>
<div id="main" class="wrapper">

<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
..
<?php get_template_part('content', get_post_format()); ?>
..
</article>

<div id="secondary" class="widget-area" role="complementary">
</div>
</div>
</div>
</body>
</html>

N’ayant plus de conteneur, notre article va s’étendre sur toute a largeur et décaler plus bas la div secondary contenant la sidebar.

Voici un rendu visuel, une fois les deux div englobantes « primary » et « content » supprimées.

mockupweb1_5

Restent la sidebar, mal placée, et le header avec son logo.

Deuxième étape, on peut créer un fichier header-single qu’on appellera avec un get_header(‘single’), (ou avec un autre nom). Dans ce header, on supprime également toute la partie concernant le logo et/ou le titre du blog, généralement placée dans des balises <hgroup></hgroup>. Sur ma page single par exemple, j’appelle désormais le header-single.

Voici un exemple pour la structure modifiée :

<html>
<head>
<title></title>
</head>
<body>
<div id="page" class="hfeed site">
<div id="main" class="wrapper">

Et voici un exemple de rendu : j’ai volontairement associé le header à l’article car une fois le logo/titre retiré, notre article ne rencontre plus d’obstacle visuel pour s’étendre sur toute la hauteur.

mockupweb1_6

Par contre, on est  toujours coincé avec notre sidebar.

La solution :

Je remets les deux div englobantes dans mon fichier single.php. J’ai toujours mon header-single en haut sans logo, les deux blocs remontent donc en haut de page

mockupweb1_7

Le fait de remettre ses conteneurs réduit la taille de l’article, ça remonte donc la sidebar à son emplacement d’origine.

Maintenant, l’astuce consiste à appliquer des conditions dans le fichier single.php, avant la div primary, pour afficher notre image ou notre slider.

L’astuce pour casser le contenu affiché par the_content();

Voici un exemple de code pour mieux comprendre:

Pour démarrer je crée une metabox pour mon post format video( à placer dans functions.php)

function add_voyage_box() {

if ( 'video' == get_post_format() ) {
add_meta_box(
'voyage_box', // $id
'Virtual Box', // $title
'display_voyage_box', // $callback
'post', // $page
'normal', // $context
'high'); // $priority
}
}

add_action('add_meta_boxes', 'add_voyage_box');
function display_voyage_box($post) {
?>
<table >
<tr>
<th align=left><h2><?php _e('Url de votre video:'); ?></h2></th>
<td>
<?php $video= get_post_meta($post->ID, 'video', true); ?>
<input type="text" name="video" id="video" value="<?php echo $video; ?>" class="requiredField" />
</td>
</tr>
</table>
<?php
}

function save_voyage_box($post) {
$video = $_POST['video'];
update_post_meta($post, 'video', $video);
}
add_action('save_post', 'save_voyage_box');

cela va me créer une metabox dans mes post format video uniquement. (il existe un moyen en javascript pour alterner l’affichage des metabox en fonction du post format, ici par exemple)

box

Dedans j’y colle l’ID d’une video youtube et pour l’afficher, dans mon fichier single:

<?php if(is_single() || has_post_format('post-format-video',$post_id)):?>
<?php
// Get the video URL and put it in the $video variable
$videoID = get_post_meta($post->ID, 'video', true);
// Check if there is in fact a video URL
if ($videoID) {
echo '<div class="videoContainer">';
// Echo the embed code via oEmbed
echo wp_oembed_get( 'http://www.youtube.com/watch?v=' . $videoID , array('width'=>1500));
echo '</div>';
}
?>

<?php endif;?>

<div id="primary" class="site-content">
<div id="content" role="main">


<?php while (have_posts()) : the_post(); ?>

<?php get_template_part('content', get_post_format()); ?>

etc.......

Une autre manière consiste non pas à récupérer l’ID mais l’url complet, ce qui est plus simple pour un client:

<?php if(  has_post_format('video')):?>
<?php
// Get the video URL and put it in the $video variable
$videoID = get_post_meta($post->ID, 'video', true);
// Check if there is in fact a video URL
if ($videoID) {
echo '<div class="videoContainer">';
// Echo the embed code via oEmbed
echo wp_oembed_get( $videoID , array('autoplay' => 1, 'rel' => 0, 'width'=>1500));
echo '</div>';
}
?>

Mon code ici génère dynamiquement une div videocontainer, et je donne les arguments pour définir ma video (taille , rel=0 pour annuler les pubs en fin de video etc…).

Comme on le voit je suis au dessus de la div primary, donc hors de ses limites. Cela va me créer exactement le rendu que je veux!!

mockupweb1_8

Comme je suis en dehors de la div primary, fixée à 60% généralement de largeur, ma video prend toute la largeur de la div parente, ici div « main »  ou div « page« ..s’il reste de la marge il est facile de la supprimer.

On peut aussi y placer le thumbail du post (l’image à la une)

<?php if(is_single() || has_post_format('post-format-video',$post_id)):?>
<?php the_post_thumbail('full');?>
<?php endif;?>

<div id="primary" class="site-content">
<div id="content" role="main">

Voici donc une manière de sortir de son contenu un élément de the_content();
En poussant plus loin, on peut  récupérer toutes les images du post et les mettre en slider comme on vient de faire pour la vidéo.