Skip to content
💻 🧠 Code 1001 > 📚 Learning Materials > 🌐 Wordpress > Code Highlighting in WordPress with Gutenberg and Prism.js

Code Highlighting in WordPress with Gutenberg and Prism.js

Gutenberg — a New Generation Editor

In the Web 1.0 era, front-end developers used the TinyMCE editor. It was a standard WYSIWYG text editor with buttons such as bold, italic, and link placed above a <textarea> field. All text was stored as a single stream of HTML code, and moving a block or inserting something in the middle was extremely inconvenient. Moreover, TinyMCE did not support the responsive 12-column layout that became the de facto standard in Web 2.0. Complex layouts had to be built manually using HTML and CSS.

The Gutenberg editor solved these problems. It was introduced in WordPress 5.0 (December 2018) and replaced the old TinyMCE text editor. Now, every part of a page exists as a separate block — a heading, paragraph, quote, image, table, or code snippet — each living independently.
This makes editing simpler and pages more flexible and responsive.

Content should display equally well on any device — from a smartphone to a widescreen monitor. When a website isn’t responsive, text “floats,” images get cropped, and tables overflow their containers. This is solved with responsive layouts that automatically adjust to the screen size.

At the core of such layouts is the 12-column grid, which became a standard thanks to frameworks like Bootstrap and Foundation. The container’s width is divided into 12 equal parts (8.33 % each), allowing developers to build virtually any page structure.

Example:

1 column → [████████████] 100%
2 columns → [██████][██████] 6/6
3 columns → [████][████][████] 4/4/4
4 columns → [███][███][███][███] 3/3/3/3

On mobile devices, columns automatically stack vertically so content remains clear and readable.


How Gutenberg Implements the Grid

In Gutenberg, the 12-column grid is implemented through the Columns block,
which automatically adjusts element placement to screen width.
In HTML, this is represented by containers with the classes wp-block-columns and wp-block-column,
and CSS uses Flexbox to control column alignment and behavior.

Example markup:

<div class="wp-block-columns">
  <div class="wp-block-column">
    <p>First column</p>
  </div>
  <div class="wp-block-column">
    <p>Second column</p>
  </div>
</div>

CSS:

.wp-block-columns {
  display: flex;
  flex-wrap: wrap;
  gap: 2em;
}
.wp-block-column {
  flex-grow: 1;
  flex-basis: 0;
}
@media (max-width: 600px) {
  .wp-block-columns {
    flex-direction: column;
  }
}

This structure makes Gutenberg flexible and ensures that a page looks consistent on any device.


The Problem with the Standard Code Block

Among all Gutenberg blocks, the Code block deserves special attention.
It’s used to display programming examples, scripts, or configuration snippets.
Technically, it’s a simple HTML container:

<pre> ... </pre>

Both Gutenberg and TinyMCE render it the same way — as monospaced text
(usually using fonts like Consolas, Courier New, or Monaco),
without syntax highlighting or line numbers.

That’s fine for general text, but when you’re writing technical articles or tutorials,
plain uncolored code quickly becomes hard to read.
The easiest way to fix this is to use Prism.js.


What Is Prism.js

Prism.js is a lightweight, client-side syntax highlighting library.
It requires no server modules — JavaScript analyzes everything inside <pre><code>...
and a CSS stylesheet (prism.css) adds colors to keywords, strings, numbers, and comments.

It supports dozens of programming languages — from HTML and JavaScript to Python and Go —
and many plugins: line numbering, copy-to-clipboard, language labels, dark/light themes, and more.

Example:

<pre><code class="language-js">
function hello(name) {
  return `Hello, ${name}!`;
}

After adding Prism.js, this code will automatically be highlighted in the browser.


Working with a Child Theme

Before adding Prism.js, it’s important not to edit the parent theme directly.
All modifications in WordPress should be made through a child theme.

A WordPress theme controls the site’s appearance — templates, styles, menus, headers, and footers.
If you edit the active theme directly, WordPress will overwrite your changes during the next update.

A child theme prevents this problem.
It inherits everything from the parent theme but stores your changes separately,
so your code stays safe after updates.

Create a folder:

/wp-content/themes/mytheme-child/

Add a file style.css:

/*
 Theme Name:   MyTheme Child
 Template:     mytheme
 Version:      1.0
*/

The Template value must match the folder name of the parent theme.
Then create functions.php:

<?php
add_action('wp_enqueue_scripts', 'child_enqueue_styles');
function child_enqueue_styles() {
    wp_enqueue_style('parent-style', get_template_directory_uri() . '/style.css');
    wp_enqueue_style('child-style',
        get_stylesheet_directory_uri() . '/style.css',
        array('parent-style')
    );
}

Activate the child theme via Appearance → Themes
and make all future edits there.


Using the Prism.js Website

Once the child theme is ready, go to the official Prism.js website:
👉 https://prismjs.com

Open the Download tab — this is the builder where you can create your custom version of the library.

Configuring Your Build

  1. Compression level: choose Minified
  2. Languages: select what you need — HTML, CSS, JavaScript, PHP, Python, JSON
  3. Plugins: recommended:
    • Line Numbers
    • Toolbar
    • Copy to Clipboard Button
    • (optional) Show Language
    • (optional) Highlight Lines

When done, scroll down and click:

  • DOWNLOAD JS — to get prism.js
  • DOWNLOAD CSS — to get prism.css

Place both files in your child theme folder:

/wp-content/themes/my-child-theme/

Connecting Prism.js to WordPress

Open functions.php in your child theme and add:

add_action('wp_enqueue_scripts', 'theme_enqueue_prism_assets');
function theme_enqueue_prism_assets() {
    $version = '1.29.0';
    wp_enqueue_style('prism-css',
        get_stylesheet_directory_uri() . '/prism.css', [], $version);
    wp_enqueue_script('prism-js',
        get_stylesheet_directory_uri() . '/prism.js', [], $version, true);
}

After that, Prism.js will automatically highlight all code inside
<pre><code>... blocks.


Automatic Line Numbering

You can use a WordPress filter to add line numbers automatically:

add_filter('render_block_core/code', 'theme_add_prism_line_numbers', 10, 2);
function theme_add_prism_line_numbers($content, $block) {
    return str_replace(
        '<pre class="wp-block-code">',
        '<pre class="wp-block-code line-numbers">',
        $content
    );
}

Escaping HTML Characters

If your code contains < or > symbols, the browser might interpret them as HTML tags.
To prevent this, add a filter to automatically escape these characters when saving a post:

add_filter('content_save_pre', 'theme_escape_code_on_save');
function theme_escape_code_on_save($content) {
    return preg_replace_callback(
        '/<code([^>]*)>(.*?)<\/code>/is',
        function ($m) {
            $attrs = $m[1];
            $code  = htmlspecialchars($m[2], ENT_NOQUOTES, 'UTF-8');
            return "<code{$attrs}>{$code}";
        },
        $content
    );
}

Styling the Code Blocks

Add these styles to your child theme’s style.css:

pre[class*="language-"] {
  border-radius: 6px;
  border: 1px solid #ddd;
  padding: 1em;
  background: #f6f8fa;
  font-family: 'Fira Code', Consolas, monospace;
  font-size: 14px;
  line-height: 1.6;
  overflow: auto;
}
pre[class*="language-"].line-numbers {
  padding-left: 3.8em;
}

Additional Features of Prism.js

  • 🔢 Line Numbers — adds numbered lines, similar to IDEs
  • 🧠 Highlight Specific Lines — emphasize lines with data-line="2,4-5"
  • 📋 Copy Button — copy code with a single click
  • 💡 Language Label — display the language name above code blocks
  • 🌗 Dark and Light Themes — enable automatic color switching:
@media (prefers-color-scheme: dark) {
  body { background: #1e1e1e; color: #d4d4d4; }
}
  • 🎨 Color Customization — override token colors if needed:
.token.keyword { color: #d73a49; font-weight: 600; }
.token.string  { color: #032f62; }
.token.comment { color: #6a737d; font-style: italic; }

Before and After Prism.js

Before

<pre><code>
function greet(name) {
  return `Hello, ${name}`;
}

Rendered result:

function greet(name) {
  return `Hello, ${name}`;
}

Plain monospaced text, no highlighting or line numbers.


After

<pre class="line-numbers"><code class="language-js">
function greet(name) {
  return `Hello, ${name}`;
}

Rendered result:

1 function greet(name) {
2   return `Hello, ${name}`;
3 }

Now each line is numbered, syntax is colored,
and a Copy button appears for quick copying.


Prism.js makes code snippets on WordPress pages more readable and visually structured.
It works entirely in the browser, requires no plugins, and doesn’t affect performance.
Once set up, every code example in your articles will look clear, consistent, and professional.

Leave a Reply

Your email address will not be published. Required fields are marked *