The default “Code” block in Gutenberg does not support syntax highlighting. The library Prism.js solves this problem. This guide describes how to set up Prism.js, including an automatic solution for issues with displaying the HTML characters < and >.
The Problem: Conflict with HTML Tags
A browser interprets the < and > characters inside code blocks as HTML tags, which breaks the page layout.
The Solution: Character Escaping
For correct display, special characters must be replaced with HTML entities:
<is replaced with<>is replaced with>
This process is automated using a WordPress filter to avoid manual replacement and issues with the Gutenberg editor.
Step-by-Step Setup
Step 0: Prepare a Child Theme
All changes must be made in a child theme to ensure they are not deleted when the parent theme is updated.
Step 1: Download and Configure a Prism.js Build
- Go to the website: prismjs.com/download.html.
- Select components:
- Compression level:
Minified. - Languages:
Markup,CSS,C-like,JavaScript. Add any other required languages. - Plugins: Line Numbers, Toolbar, Copy to Clipboard Button.
- Compression level:
- Download the files: Click DOWNLOAD JS and DOWNLOAD CSS.
Place the downloaded prism.js and prism.css files in the root folder of your child theme.
Step 2: Enqueue Files in functions.php
To enqueue the files in WordPress, open your child theme’s functions.php and add the following code:
<?php
/**
* Enqueue styles and scripts for code highlighting.
*/
add_action('wp_enqueue_scripts', 'theme_enqueue_prism_assets');
function theme_enqueue_prism_assets() {
// Enqueue Prism styles
wp_enqueue_style(
'prism-css',
get_stylesheet_directory_uri() . '/prism.css',
array(),
'1.29.0' // Version for cache busting
);
// Enqueue Prism script
wp_enqueue_script(
'prism-js',
get_stylesheet_directory_uri() . '/prism.js',
array(),
'1.29.0',
true // Load in the footer
);
}
/**
* Automatically add classes to Gutenberg code blocks.
*/
add_filter('render_block_core/code', 'theme_add_prism_classes_to_code_block', 10, 2);
function theme_add_prism_classes_to_code_block($block_content, $block) {
// Add the line-numbers class to the <pre> tag
$block_content = str_replace('<pre class="wp-block-code">', '<pre class="wp-block-code line-numbers">', $block_content);
return $block_content;
}
This code enqueues the files and activates line numbering.
Step 3: Automatically Escape Characters
The key step is to add a filter to functions.php to automatically escape special characters before saving the post.
/** * Escape HTML characters inside <code> tags when a post is saved. */ add_filter('content_save_pre', 'theme_escape_code_on_save'); function theme_escape_code_on_save($content) { // Find all <code>...blocks return preg_replace_callback('/(.*?)<\/code>/is', function($matches) { $attributes = $matches[1]; // Tag attributes $code_content = $matches[2]; // Tag content // Escape the content $escaped_content = htmlspecialchars($code_content, ENT_NOQUOTES, 'UTF-8'); // Reassemble the tag return '<code' . $attributes . '>' . $escaped_content . ''; }, $content); }
The content_save_pre hook triggers before writing to the database. The htmlspecialchars function converts special characters into safe HTML entities.
Step 4: Styling in style.css
For a clean presentation, add the following styles to your child theme’s style.css file:
/* Styles for code blocks */
pre[class*="language-"] {
border-radius: 5px;
border: 1px solid #ddd;
font-size: 14px;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
/* Styles for the Prism toolbar */
div.code-toolbar {
position: relative;
}
div.code-toolbar > .toolbar {
position: absolute;
top: 10px;
right: 10px;
opacity: 0;
transition: opacity 0.3s ease-in-out;
}
div.code-toolbar:hover > .toolbar {
opacity: 1; /* Show button on hover */
}
.toolbar-item button {
padding: 5px 10px;
background: #f5f5f5;
color: #333;
border: 1px solid #ddd;
border-radius: 3px;
font-size: 13px;
cursor: pointer;
}
.toolbar-item button:hover {
background-color: #e0e0e0;
}
Result
After completing these steps, every code block in Gutenberg will have:
- Automatic syntax highlighting.
- Line numbers.
- A copy button.
- Correct rendering of HTML tags without breaking the layout.