La création de thèmes WordPress modernes nécessite des outils adaptés aux exigences actuelles. Je partage ici mon approche pour créer des thèmes performants et maintenables avec Tailwind CSS et Vite.
Architecture du thème
1. Structure de base optimisée
theme/
├── assets/
│ ├── css/
│ │ └── app.css
│ └── js/
│ └── app.js
├── inc/
│ ├── customizer.php
│ ├── helpers.php
│ └── setup.php
├── templates/
│ ├── components/
│ └── partials/
├── package.json
├── tailwind.config.js
└── vite.config.js
2. Configuration Tailwind optimisée
// tailwind.config.js
module.exports = {
content: [
'./templates/**/*.php',
'./inc/**/*.php',
'./assets/js/**/*.js'
],
theme: {
extend: {
colors: {
'wp-admin': '#2271b1',
'wp-link': '#0073aa'
},
typography: {
DEFAULT: {
css: {
'max-width': '65ch',
color: 'inherit'
}
}
}
}
},
plugins: [
require('@tailwindcss/typography'),
require('@tailwindcss/forms')
]
};
3. Intégration Vite pour le développement
// vite.config.js
export default {
build: {
manifest: true,
outDir: 'dist',
rollupOptions: {
input: {
app: '/assets/js/app.js',
admin: '/assets/js/admin.js'
}
}
},
plugins: [
{
name: 'php',
handleHotUpdate({ file, server }) {
if (file.endsWith('.php')) {
server.ws.send({ type: 'full-reload' });
}
}
}
]
};
Composants réutilisables
1. Système de cartes flexible
// templates/components/card.php
function get_card($args = []) {
$defaults = [
'title' => '',
'image' => '',
'excerpt' => '',
'link' => '',
'classes' => ''
];
$props = wp_parse_args($args, $defaults);
ob_start(); ?>
<article class="bg-white rounded-lg shadow-lg overflow-hidden <?php echo esc_attr($props['classes']); ?>">
<?php if ($props['image']) : ?>
<img src="<?php echo esc_url($props['image']); ?>"
alt="<?php echo esc_attr($props['title']); ?>"
class="w-full h-48 object-cover"
loading="lazy">
<?php endif; ?>
<div class="p-6">
<h3 class="text-xl font-semibold mb-2">
<?php echo esc_html($props['title']); ?>
</h3>
<?php if ($props['excerpt']) : ?>
<p class="text-gray-600 mb-4">
<?php echo wp_kses_post($props['excerpt']); ?>
</p>
<?php endif; ?>
<?php if ($props['link']) : ?>
<a href="<?php echo esc_url($props['link']); ?>"
class="inline-block bg-primary-600 text-white px-4 py-2 rounded-lg hover:bg-primary-700 transition-colors">
Lire la suite
</a>
<?php endif; ?>
</div>
</article>
<?php
return ob_get_clean();
}
2. Navigation responsive
// templates/partials/navigation.php
<nav x-data="{ open: false }" class="bg-white shadow-lg">
<div class="max-w-7xl mx-auto px-4">
<div class="flex justify-between h-16">
<!-- Logo -->
<div class="flex-shrink-0 flex items-center">
<?php if (has_custom_logo()) : ?>
<?php the_custom_logo(); ?>
<?php else : ?>
<a href="<?php echo esc_url(home_url('/')); ?>" class="text-xl font-bold">
<?php bloginfo('name'); ?>
</a>
<?php endif; ?>
</div>
<!-- Menu principal -->
<?php
wp_nav_menu([
'theme_location' => 'primary',
'container' => false,
'menu_class' => 'hidden md:flex space-x-8',
'fallback_cb' => false,
'items_wrap' => '<ul class="%2$s">%3$s</ul>',
'walker' => new TailwindMenuWalker()
]);
?>
<!-- Bouton mobile -->
<button @click="open = !open" class="md:hidden">
<span class="sr-only">Menu</span>
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path x-show="!open" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
<path x-show="open" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
</div>
</div>
<!-- Menu mobile -->
<div x-show="open" class="md:hidden">
<?php
wp_nav_menu([
'theme_location' => 'primary',
'container' => false,
'menu_class' => 'px-2 pt-2 pb-3 space-y-1',
'fallback_cb' => false
]);
?>
</div>
</nav>
Optimisations de performance
1. Chargement des assets
function theme_enqueue_assets() {
$manifest = json_decode(
file_get_contents(get_template_directory() . '/dist/manifest.json'),
true
);
wp_enqueue_style(
'theme-styles',
get_template_directory_uri() . '/dist/' . $manifest['app.css'],
[],
null
);
wp_enqueue_script(
'theme-scripts',
get_template_directory_uri() . '/dist/' . $manifest['app.js'],
[],
null,
true
);
}
add_action('wp_enqueue_scripts', 'theme_enqueue_assets');
2. Optimisation des images
add_theme_support('post-thumbnails');
add_image_size('card-thumb', 800, 600, true);
add_image_size('hero', 1920, 1080, true);
function optimize_image_sizes($sizes) {
unset($sizes['medium_large']);
return $sizes;
}
add_filter('intermediate_image_sizes_advanced', 'optimize_image_sizes');
Intégration Gutenberg
1. Styles personnalisés
function theme_gutenberg_styles() {
add_theme_support('editor-styles');
add_editor_style('dist/editor.css');
add_theme_support('custom-spacing');
add_theme_support('custom-units');
add_theme_support('appearance-tools');
}
add_action('after_setup_theme', 'theme_gutenberg_styles');
2. Blocs personnalisés
function register_custom_blocks() {
register_block_type('theme/cta', [
'editor_script' => 'theme-blocks',
'render_callback' => function($attributes) {
return sprintf(
'<div class="wp-block-theme-cta bg-primary-100 p-8 rounded-lg">
<h2 class="text-2xl font-bold mb-4">%s</h2>
<p class="mb-6">%s</p>
<a href="%s" class="btn btn-primary">%s</a>
</div>',
esc_html($attributes['title']),
esc_html($attributes['content']),
esc_url($attributes['link']),
esc_html($attributes['buttonText'])
);
}
]);
}
add_action('init', 'register_custom_blocks');
Résultats
Les thèmes créés avec cette architecture obtiennent :
- Score PageSpeed > 95
- Temps de chargement < 1s
- Excellente maintenabilité
- Support complet de Gutenberg
Conclusion
Cette approche moderne de création de thèmes WordPress combine le meilleur des outils actuels pour un résultat optimal. Si vous cherchez à moderniser votre thème WordPress ou à en créer un nouveau, je peux vous accompagner dans cette démarche.