customiser la page d'erreur 404 de Joomla

Comment customiser la page d'erreur 404 de Joomla

L'affichage d'une page d'erreur 404 signale la présence d'une page inexistante ou manquante. Et il faut bien l'avouer, la page affichant cette erreur 404 par défaut dans Joomla est très basique visuellement. En dehors du fait qu'elle n'est probablement pas adaptée à la charte graphique de votre site, elle n'aide pas non plus l'internaute à trouver ce qu'il cherchait et ne l'incite pas à rester sur votre site.

Fort de ce constat, il peut être intéressant d'afficher une page d'erreur qui soit plus adaptée et surtout plus informative pour vos visiteurs. Au cours de ce tutoriel, je vais vous montrer comment customiser la page d'erreur 404 par défaut de Joomla 4 afin qu'elle réponde parfaitement aux problématiques suivantes :

  • Intégrée à la charte graphique de votre site,
  • Permette aux visiteurs de continuer à naviguer sur votre site,

customiser la page d'erreur 404 de Joomla

>La page d'erreur par défaut de Joomla 4

Cette page est générée grâce au fichier error.php qui est présent dans le dossier de votre template.

C'est donc ce fichier que nous allons devoir modifier pour personnaliser notre page d'erreur.

Si vous avez besoin d'inspiration, vous trouverez également sur mon blog, un article sur le contenu d'une bonne page 404 ainsi que quelques exemples chez Smashing Magazine.

Lorsque vous aurez pris le temps de lire ces conseils, vous pourrez passer à l'étape suivante.

Modification du fichier error.php pour customiser la page d'erreur 404 de Joomla

  • Depuis le panneau d'administration de Joomla 4, cliquez sur Système dans le menu latéral de gauche,
  • Dans la rubrique Templates cliquez sur Templates du site
  • Cliquez sur le nom de votre template (Cassiopeia, dans cet exemple)
  • Sur la gauche de votre écran, vous avez la liste des dossiers et des fichiers de votre template

    Cliquez sur le fichier error.php pour l'ouvrir dans l'éditeur de texte

    Fichier error.php de Cassiopeia

  • Supprimez tout le code compris entre les lignes 157 à 201

    Si vous avez peur de faire une bêtise,

    • copiez/collez tout ce code dans un bloc-notes,
    • enregistrez ce fichier dans vos documents,
    • supprimez le ensuite du fichier error.php
  • A la place, copiez/collez le code suivant :

    <div class="text-center pt-2">
     		<h1 class="fw-bold display-1">404</h1>
      		<h2 class="">page not found!</h2>
    	</div>
    
    	<div class="d-flex justify-content-center" style='padding-bottom:30%'>
          <iframe class="" src='https://gfycat.com/ifr/AccurateUnfinishedBergerpicard' frameborder='0' scrolling='no' width="600" height="700" style='border-style: hidden !important;position:absolute;top:100px;'></iframe>
      	</div>
  • Enregistrez votre saisie

Maintenant, vous devriez obtenir une page d'erreur ressemblant à celle-ci :

customiser la page d'erreur 404 de Joomla

Si vous souhaitez afficher autre chose que ce .GIF, supprimez ou remplacez l'iframe par le contenu de votre choix.

Code définitif du fichier ' error.php '

<?php
/**
 * @package     Joomla.Site
 * @subpackage  Templates.cassiopeia
 * @author	    web-eau.net
 * @copyright   (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

                
use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Uri\Uri;

/** @var Joomla\CMS\Document\ErrorDocument $this */

$app = Factory::getApplication();
$wa  = $this->getWebAssetManager();

// Detecting Active Variables
$option   = $app->input->getCmd('option', '');
$view     = $app->input->getCmd('view', '');
$layout   = $app->input->getCmd('layout', '');
$task     = $app->input->getCmd('task', '');
$itemid   = $app->input->getCmd('Itemid', '');
$sitename = htmlspecialchars($app->get('sitename'), ENT_QUOTES, 'UTF-8');
$menu     = $app->getMenu()->getActive();
$pageclass = $menu !== null ? $menu->getParams()->get('pageclass_sfx', '') : '';

// Template path
$templatePath = 'templates/' . $this->template;

// Color Theme
$paramsColorName = $this->params->get('colorName', 'colors_standard');
$assetColorName  = 'theme.' . $paramsColorName;
$wa->registerAndUseStyle($assetColorName, $templatePath . '/css/global/' . $paramsColorName . '.css');

// Use a font scheme if set in the template style options
$paramsFontScheme = $this->params->get('useFontScheme', false);
$fontStyles       = '';

if ($paramsFontScheme)
{
	if (stripos($paramsFontScheme, 'https://') === 0)
	{
		$this->getPreloadManager()->preconnect('https://fonts.googleapis.com/', []);
		$this->getPreloadManager()->preconnect('https://fonts.gstatic.com/', []);
		$this->getPreloadManager()->preload($paramsFontScheme, ['as' => 'style']);
		$wa->registerAndUseStyle('fontscheme.current', $paramsFontScheme, [], ['media' => 'print', 'rel' => 'lazy-stylesheet', 'onload' => 'this.media=\'all\'']);

		if (preg_match_all('/family=([^?:]*):/i', $paramsFontScheme, $matches) > 0)
		{
			$fontStyles = '--cassiopeia-font-family-body: "' . str_replace('+', ' ', $matches[1][0]) . '", sans-serif;
			--cassiopeia-font-family-headings: "' . str_replace('+', ' ', isset($matches[1][1]) ? $matches[1][1] : $matches[1][0]) . '", sans-serif;
			--cassiopeia-font-weight-normal: 400;
			--cassiopeia-font-weight-headings: 700;';
		}
	}
	else
	{
		$wa->registerAndUseStyle('fontscheme.current', $paramsFontScheme, ['version' => 'auto'], ['media' => 'print', 'rel' => 'lazy-stylesheet', 'onload' => 'this.media=\'all\'']);
		$this->getPreloadManager()->preload($wa->getAsset('style', 'fontscheme.current')->getUri() . '?' . $this->getMediaVersion(), ['as' => 'style']);
	}
}

// Enable assets
$wa->usePreset('template.cassiopeia.' . ($this->direction === 'rtl' ? 'rtl' : 'ltr'))
	->useStyle('template.active.language')
	->useStyle('template.user')
	->useScript('template.user')
	->addInlineStyle(":root {
		--hue: 214;
		--template-bg-light: #f0f4fb;
		--template-text-dark: #495057;
		--template-text-light: #ffffff;
		--template-link-color: #2a69b8;
		--template-special-color: #001B4C;
		$fontStyles
	}");

// Override 'template.active' asset to set correct ltr/rtl dependency
$wa->registerStyle('template.active', '', [], [], ['template.cassiopeia.' . ($this->direction === 'rtl' ? 'rtl' : 'ltr')]);

// Browsers support SVG favicons
$this->addHeadLink(HTMLHelper::_('image', 'joomla-favicon.svg', '', [], true, 1), 'icon', 'rel', ['type' => 'image/svg+xml']);
$this->addHeadLink(HTMLHelper::_('image', 'favicon.ico', '', [], true, 1), 'alternate icon', 'rel', ['type' => 'image/vnd.microsoft.icon']);
$this->addHeadLink(HTMLHelper::_('image', 'joomla-favicon-pinned.svg', '', [], true, 1), 'mask-icon', 'rel', ['color' => '#000']);

// Logo file or site title param
if ($this->params->get('logoFile'))
{
	$logo = '<img src="' . htmlspecialchars(Uri::root() . $this->params->get('logoFile'), ENT_QUOTES, 'UTF-8') . '" alt="' . $sitename . '">';
}
elseif ($this->params->get('siteTitle'))
{
	$logo = '<span title="' . $sitename . '">' . htmlspecialchars($this->params->get('siteTitle'), ENT_COMPAT, 'UTF-8') . '</span>';
}
else
{
	$logo = '<img src="' . $this->baseurl . '/' . $templatePath. '/images/logo.svg" class="logo d-inline-block" alt="' . $sitename . '">';
}

// Container
$wrapper = $this->params->get('fluidContainer') ? 'wrapper-fluid' : 'wrapper-static';

$this->setMetaData('viewport', 'width=device-width, initial-scale=1');

// Defer font awesome
$wa->getAsset('style', 'fontawesome')->setAttribute('rel', 'lazy-stylesheet');
?>
<!DOCTYPE html>
<html lang="<?php echo $this->language; ?>" dir="<?php echo $this->direction; ?>">
<head>
	<jdoc:include type="metas" />
	<jdoc:include type="styles" />
	<jdoc:include type="scripts" />
</head>

<body class="site error_site <?php echo $option
	. ' ' . $wrapper
	. ' view-' . $view
	. ($layout ? ' layout-' . $layout : ' no-layout')
	. ($task ? ' task-' . $task : ' no-task')
	. ($itemid ? ' itemid-' . $itemid : '')
	. ' ' . $pageclass;
	echo ($this->direction == 'rtl' ? ' rtl' : '');
?>">
	<header class="header container-header full-width">
		<?php if ($this->params->get('brand', 1)) : ?>
			<div class="grid-child">
				<div class="navbar-brand">
					<a class="brand-logo" href="<?php echo $this->baseurl; ?>/">
						<?php echo $logo; ?>
					</a>
					<?php if ($this->params->get('siteDescription')) : ?>
						<div class="site-description"><?php echo htmlspecialchars($this->params->get('siteDescription')); ?></div>
					<?php endif; ?>
				</div>
			</div>
		<?php endif; ?>
		<?php if ($this->countModules('menu') || $this->countModules('search')) : ?>
			<div class="grid-child container-nav">
				<?php if ($this->countModules('menu')) : ?>
					<jdoc:include type="modules" name="menu" style="none" />
				<?php endif; ?>
				<?php if ($this->countModules('search')) : ?>
					<div class="container-search">
						<jdoc:include type="modules" name="search" style="none" />
					</div>
				<?php endif; ?>
			</div>
		<?php endif; ?>
	</header>

	<div class="text-center mt-3">
		<h1 class="fw-bold display-1">404</h1>
		<h2 class="">page not found!</h2>
	</div>

	<div class="d-flex justify-content-center" style='padding-top: 50px;padding-bottom:35%'>
		<iframe class="pt-5 mt-5" src='https://gfycat.com/ifr/AccurateUnfinishedBergerpicard' frameborder='0' scrolling='no' width="600" height="700" style='position:absolute;top:100px;'></iframe>
	</div>

	<?php if ($this->countModules('footer')) : ?>
	<footer class="container-footer footer full-width">
		<div class="grid-child">
			<jdoc:include type="modules" name="footer" style="none" />
		</div>
	</footer>
	<?php endif; ?>

	<jdoc:include type="modules" name="debug" style="none" />
</body>
</html>

Conclusion

Voilà, ce n'est pas plus compliqué que ça que de customiser la page d'erreur de Joomla 4.
N'oubliez pas, une page d'erreur 404 peut drôle mais peut aussi être l'occasion de donner un coup de pouce à une démarche environnementale ou à une cause humanitaire. Laissez votre créativité s'exprimer et créez une page d'erreur qui soit informative et qui ne fasse pas fuir vos internautes. C'est à vous de jouer !

L'affichage d'une page d'erreur 404 signale la présence d'une page inexistante ou manquante. Et il faut bien l'avouer, la page affichant cette erreur 404 par défaut dans Joomla est très basique visuellement. En dehors du fait qu'elle n'est probablement pas adaptée à la charte graphique de votre site, elle n'aide pas non plus l'internaute à trouver ce qu'il cherchait et ne l'incite pas à rester sur votre site.

Fort de ce constat, il peut être intéressant d'afficher une page d'erreur qui soit plus adaptée et surtout plus informative pour vos visiteurs. Au cours de ce tutoriel, je vais vous montrer comment customiser la page d'erreur 404 par défaut de Joomla 4 afin qu'elle réponde parfaitement aux problématiques suivantes :

  • Intégrée à la charte graphique de votre site,
  • Permette aux visiteurs de continuer à naviguer sur votre site,

customiser la page d'erreur 404 de Joomla

>La page d'erreur par défaut de Joomla 4

Cette page est générée grâce au fichier error.php qui est présent dans le dossier de votre template.

C'est donc ce fichier que nous allons devoir modifier pour personnaliser notre page d'erreur.

Si vous avez besoin d'inspiration, vous trouverez également sur mon blog, un article sur le contenu d'une bonne page 404 ainsi que quelques exemples chez Smashing Magazine.

Lorsque vous aurez pris le temps de lire ces conseils, vous pourrez passer à l'étape suivante.

Modification du fichier error.php pour customiser la page d'erreur 404 de Joomla

  • Depuis le panneau d'administration de Joomla 4, cliquez sur Système dans le menu latéral de gauche,
  • Dans la rubrique Templates cliquez sur Templates du site
  • Cliquez sur le nom de votre template (Cassiopeia, dans cet exemple)
  • Sur la gauche de votre écran, vous avez la liste des dossiers et des fichiers de votre template

    Cliquez sur le fichier error.php pour l'ouvrir dans l'éditeur de texte

    Fichier error.php de Cassiopeia

  • Supprimez tout le code compris entre les lignes 157 à 201

    Si vous avez peur de faire une bêtise,

    • copiez/collez tout ce code dans un bloc-notes,
    • enregistrez ce fichier dans vos documents,
    • supprimez le ensuite du fichier error.php
  • A la place, copiez/collez le code suivant :

    <div class="text-center pt-2">
     		<h1 class="fw-bold display-1">404</h1>
      		<h2 class="">page not found!</h2>
    	</div>
    
    	<div class="d-flex justify-content-center" style='padding-bottom:30%'>
          <iframe class="" src='https://gfycat.com/ifr/AccurateUnfinishedBergerpicard' frameborder='0' scrolling='no' width="600" height="700" style='border-style: hidden !important;position:absolute;top:100px;'></iframe>
      	</div>
  • Enregistrez votre saisie

Maintenant, vous devriez obtenir une page d'erreur ressemblant à celle-ci :

customiser la page d'erreur 404 de Joomla

Si vous souhaitez afficher autre chose que ce .GIF, supprimez ou remplacez l'iframe par le contenu de votre choix.

Code définitif du fichier ' error.php '

<?php
/**
 * @package     Joomla.Site
 * @subpackage  Templates.cassiopeia
 * @author	    web-eau.net
 * @copyright   (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

                
use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Uri\Uri;

/** @var Joomla\CMS\Document\ErrorDocument $this */

$app = Factory::getApplication();
$wa  = $this->getWebAssetManager();

// Detecting Active Variables
$option   = $app->input->getCmd('option', '');
$view     = $app->input->getCmd('view', '');
$layout   = $app->input->getCmd('layout', '');
$task     = $app->input->getCmd('task', '');
$itemid   = $app->input->getCmd('Itemid', '');
$sitename = htmlspecialchars($app->get('sitename'), ENT_QUOTES, 'UTF-8');
$menu     = $app->getMenu()->getActive();
$pageclass = $menu !== null ? $menu->getParams()->get('pageclass_sfx', '') : '';

// Template path
$templatePath = 'templates/' . $this->template;

// Color Theme
$paramsColorName = $this->params->get('colorName', 'colors_standard');
$assetColorName  = 'theme.' . $paramsColorName;
$wa->registerAndUseStyle($assetColorName, $templatePath . '/css/global/' . $paramsColorName . '.css');

// Use a font scheme if set in the template style options
$paramsFontScheme = $this->params->get('useFontScheme', false);
$fontStyles       = '';

if ($paramsFontScheme)
{
	if (stripos($paramsFontScheme, 'https://') === 0)
	{
		$this->getPreloadManager()->preconnect('https://fonts.googleapis.com/', []);
		$this->getPreloadManager()->preconnect('https://fonts.gstatic.com/', []);
		$this->getPreloadManager()->preload($paramsFontScheme, ['as' => 'style']);
		$wa->registerAndUseStyle('fontscheme.current', $paramsFontScheme, [], ['media' => 'print', 'rel' => 'lazy-stylesheet', 'onload' => 'this.media=\'all\'']);

		if (preg_match_all('/family=([^?:]*):/i', $paramsFontScheme, $matches) > 0)
		{
			$fontStyles = '--cassiopeia-font-family-body: "' . str_replace('+', ' ', $matches[1][0]) . '", sans-serif;
			--cassiopeia-font-family-headings: "' . str_replace('+', ' ', isset($matches[1][1]) ? $matches[1][1] : $matches[1][0]) . '", sans-serif;
			--cassiopeia-font-weight-normal: 400;
			--cassiopeia-font-weight-headings: 700;';
		}
	}
	else
	{
		$wa->registerAndUseStyle('fontscheme.current', $paramsFontScheme, ['version' => 'auto'], ['media' => 'print', 'rel' => 'lazy-stylesheet', 'onload' => 'this.media=\'all\'']);
		$this->getPreloadManager()->preload($wa->getAsset('style', 'fontscheme.current')->getUri() . '?' . $this->getMediaVersion(), ['as' => 'style']);
	}
}

// Enable assets
$wa->usePreset('template.cassiopeia.' . ($this->direction === 'rtl' ? 'rtl' : 'ltr'))
	->useStyle('template.active.language')
	->useStyle('template.user')
	->useScript('template.user')
	->addInlineStyle(":root {
		--hue: 214;
		--template-bg-light: #f0f4fb;
		--template-text-dark: #495057;
		--template-text-light: #ffffff;
		--template-link-color: #2a69b8;
		--template-special-color: #001B4C;
		$fontStyles
	}");

// Override 'template.active' asset to set correct ltr/rtl dependency
$wa->registerStyle('template.active', '', [], [], ['template.cassiopeia.' . ($this->direction === 'rtl' ? 'rtl' : 'ltr')]);

// Browsers support SVG favicons
$this->addHeadLink(HTMLHelper::_('image', 'joomla-favicon.svg', '', [], true, 1), 'icon', 'rel', ['type' => 'image/svg+xml']);
$this->addHeadLink(HTMLHelper::_('image', 'favicon.ico', '', [], true, 1), 'alternate icon', 'rel', ['type' => 'image/vnd.microsoft.icon']);
$this->addHeadLink(HTMLHelper::_('image', 'joomla-favicon-pinned.svg', '', [], true, 1), 'mask-icon', 'rel', ['color' => '#000']);

// Logo file or site title param
if ($this->params->get('logoFile'))
{
	$logo = '<img src="' . htmlspecialchars(Uri::root() . $this->params->get('logoFile'), ENT_QUOTES, 'UTF-8') . '" alt="' . $sitename . '">';
}
elseif ($this->params->get('siteTitle'))
{
	$logo = '<span title="' . $sitename . '">' . htmlspecialchars($this->params->get('siteTitle'), ENT_COMPAT, 'UTF-8') . '</span>';
}
else
{
	$logo = '<img src="' . $this->baseurl . '/' . $templatePath. '/images/logo.svg" class="logo d-inline-block" alt="' . $sitename . '">';
}

// Container
$wrapper = $this->params->get('fluidContainer') ? 'wrapper-fluid' : 'wrapper-static';

$this->setMetaData('viewport', 'width=device-width, initial-scale=1');

// Defer font awesome
$wa->getAsset('style', 'fontawesome')->setAttribute('rel', 'lazy-stylesheet');
?>
<!DOCTYPE html>
<html lang="<?php echo $this->language; ?>" dir="<?php echo $this->direction; ?>">
<head>
	<jdoc:include type="metas" />
	<jdoc:include type="styles" />
	<jdoc:include type="scripts" />
</head>

<body class="site error_site <?php echo $option
	. ' ' . $wrapper
	. ' view-' . $view
	. ($layout ? ' layout-' . $layout : ' no-layout')
	. ($task ? ' task-' . $task : ' no-task')
	. ($itemid ? ' itemid-' . $itemid : '')
	. ' ' . $pageclass;
	echo ($this->direction == 'rtl' ? ' rtl' : '');
?>">
	<header class="header container-header full-width">
		<?php if ($this->params->get('brand', 1)) : ?>
			<div class="grid-child">
				<div class="navbar-brand">
					<a class="brand-logo" href="<?php echo $this->baseurl; ?>/">
						<?php echo $logo; ?>
					</a>
					<?php if ($this->params->get('siteDescription')) : ?>
						<div class="site-description"><?php echo htmlspecialchars($this->params->get('siteDescription')); ?></div>
					<?php endif; ?>
				</div>
			</div>
		<?php endif; ?>
		<?php if ($this->countModules('menu') || $this->countModules('search')) : ?>
			<div class="grid-child container-nav">
				<?php if ($this->countModules('menu')) : ?>
					<jdoc:include type="modules" name="menu" style="none" />
				<?php endif; ?>
				<?php if ($this->countModules('search')) : ?>
					<div class="container-search">
						<jdoc:include type="modules" name="search" style="none" />
					</div>
				<?php endif; ?>
			</div>
		<?php endif; ?>
	</header>

	<div class="text-center mt-3">
		<h1 class="fw-bold display-1">404</h1>
		<h2 class="">page not found!</h2>
	</div>

	<div class="d-flex justify-content-center" style='padding-top: 50px;padding-bottom:35%'>
		<iframe class="pt-5 mt-5" src='https://gfycat.com/ifr/AccurateUnfinishedBergerpicard' frameborder='0' scrolling='no' width="600" height="700" style='position:absolute;top:100px;'></iframe>
	</div>

	<?php if ($this->countModules('footer')) : ?>
	<footer class="container-footer footer full-width">
		<div class="grid-child">
			<jdoc:include type="modules" name="footer" style="none" />
		</div>
	</footer>
	<?php endif; ?>

	<jdoc:include type="modules" name="debug" style="none" />
</body>
</html>

Conclusion

Voilà, ce n'est pas plus compliqué que ça que de customiser la page d'erreur de Joomla 4.
N'oubliez pas, une page d'erreur 404 peut drôle mais peut aussi être l'occasion de donner un coup de pouce à une démarche environnementale ou à une cause humanitaire. Laissez votre créativité s'exprimer et créez une page d'erreur qui soit informative et qui ne fasse pas fuir vos internautes. C'est à vous de jouer !

Daniel Dubois - auteur à web-eau.net

A propos de Daniel

Passionné par le Web depuis 2007, Daniel défend la veuve et l'orphelin du web en créant des sites respectueux du W3C. Fort de son expérience, il partage ses connaissances dans un état d'esprit open source. Très impliqué en faveur du CMS Joomla depuis 2014, il est également conférencier et fondateur du Joomla User Group Breizh.

web-eau.net

29800 Landerneau

06 74 50 27 99

daniel@web-eau.net