Make Syntax Highlighting work in AMP-WP using GeSHi

Again another Google AMP article, this time dealing with Syntax Highlighting. If you have a code centric website, this is important.

In one of my last articles I talked about a Generic Syntax Highlighter.   This time I want to show you, how to add Syntax Highlighting with GeSHi to a custom template in AMP-WP.


Please read up on documentation, as I am not diving into every detail.

  1. / Documentation
    The WordPress AMP integration. We will be using a custom template for our AMP pages.
  2. Crayon Syntax Highlighter
    I am using this for Syntax Highlighting on none AMP pages. It adds specific language classes to the code / pre areas, that I am using to configure GeSHi.
    The Syntax Highlighter
    DOM Document transversal & modification simplified. You should be able to apply the things below with any other tool as well.
  5. My tweaks on GitHub


  1. Upload GeSHi and phpQuery to your desired location on your webserver.
  2. Call the custom template for AMP-WP in your functions.php
    1. add_filter( 'amp_post_template_file', 'xyz_amp_set_custom_template', 10, 3 );
    3. function xyz_amp_set_custom_template( $file, $type, $post ) {
    4.     if ( 'single' === $type ) {
    5.         $file = dirname( __FILE__ ) . '/templates/my-amp-template.php';
    6.     }
    7.     return $file;
    8. }

    I have an example stored on GitHub

  3. Create a custom template in your themes folder.We could use the following filters, but its easier to use the custom template, due to the GeSHi style setup. The problem is, that the style action is called before the content action within the template. But I am planning to build a TWIG template for myself, as I am running Timber everywhere. That will detach logic and content completely, allowing to rethink some of these things and make styling a lot easier :) So watch out for my next article!
    1. add_action( 'pre_amp_render_post', 'xyz_amp_add_custom_actions' );
    2. add_action( 'amp_post_template_css', 'xyz_amp_my_additional_css_styles' );

    Add this to the top of your custom template:

    1.  // Load phpQuery
    2. require ('my-libs/phpQuery/phpQuery.php');
    4. // Load GesSHi
    5. require ('my-libs/geshi/geshi.php');
    7. // Get AMP content and add it to phpQuery
    9. $doc = phpQuery::newDocumentHTML($this->get('post_amp_content'));
    10. $highlight = array();
    12. // Loop through the code snippets (pre tags)
    14. foreach(pq('pre') as $snippet) {
    16.         // Get classes of tag
    18.         $class = pq($snippet)->attr("class");
    20.         // Check for Crayon Syntax Highlighter Class
    22.         if (strpos($class, "lang:") !== false && strpos($class, "lang:default") === false) {
    23.                 preg_match("/lang:(?P<lang>\w+)/", $class, $catch);
    24.         }
    25.         else {
    27.                 // Fallback, if no language is detected
    29.                 $catch['lang'] = "php";
    30.         }
    32.         // New Syntax Highlighter for each code snippet, with the correct language set
    33.         // Storing for later stylesheet output. This makes also sure that stylesheets are only loaded once.
    35.         $highlight[$catch['lang']] = new GeSHi(pq($snippet)->text() , $catch['lang']);
    37.         // Uses Classes and no inlien styles
    39.         $highlight[$catch['lang']]->enable_classes();
    41.         // Update code snippet
    43.         $html = pq($snippet)->html($highlight[$catch['lang']]->parse_code());
    44. }

    I have an example stored on GitHub. The above works, if you are using Crayon Syntax Highlighter for standard pages.
    If you use something else, this needs to be changed.

  4. Add the GeSHi styles to the amp-custom style tag
    1. <style amp-custom>
    2. <?php $this->load_parts( array( 'style' ) );
    3. ?><?php
    4.  do_action( 'amp_post_template_css', $this );
    6.  // Load Stylesheets for highlighted languages
    8.  foreach($highlight as $store){
    9.   echo $store->get_stylesheet();
    10.  }
    11. ?>
    12. </style>

    I have an example stored on GitHub.

  5. Output updated amp-wp-content
    1. <div class="amp-wp-content">
    2.         <h1 class="amp-wp-title"><?php echo wp_kses_data( $this->get( 'post_title' ) ); ?></h1>
    3.         <ul class="amp-wp-meta">
    4.                 <?php $this->load_parts( apply_filters( 'amp_post_template_meta_parts', array( 'meta-author', 'meta-time', 'meta-taxonomy' ) ) ); ?>
    5.         </ul>
    6.         <?php  echo  $doc->html();  // amphtml content; no kses ?>
    7. </div>

    I have an example stored on GitHub.

  6. Save and check that your AMP page validates, by adding #development=1 to the end of the url. Check the console for errors.
    Show this page as AMP

Enjoy coding …

Alex @portalzine

I am a full-stack developer.

I love programming,  design and know my way around server architecture as well.  I would never feel complete, with one of these missing.

I have a broad range of interests, that’s why I constantly dive into new technologies and expand my knowledge where ever required. Technologies are evolving fast and I enjoy using the latest.

Apart from that, I am a peace loving guy who tries to have people around him that think the same.  I truly believe in the principle: “If you help someone, someone will help you, when you need it."

Recent Posts

  • API
  • Database
  • Deployment
  • Development
  • Hosting
  • Node.js
  • PHP
  • Security
  • WordPress

Keeping Development Credentials Secure

Development today relies on multiple teams, services, and environments all working in unison. A topic that always comes up, when… Read More

4 weeks ago
  • Deployment
  • Development
  • Home Automation
  • Hosting
  • IoT

Cron / Crontab Tips Collection

I will use this article to collect interesting tips and tricks about using the Linux cron. This is not so… Read More

1 month ago
  • API
  • Bootstrap
  • CSS
  • Database
  • Deployment
  • Design
  • Development
  • Essentials
  • Hosting
  • HTML5
  • Javascript
  • Mobile
  • Node.js
  • WordPress

Have you heard of GatsbyJS?

Gatsby is a free and open source framework based on React that helps developers build blazing fast websites and apps. What they have… Read More

2 months ago
  • Consulting
  • Custom Design
  • Data Import / Export
  • Development
  • Documentation
  • Hosting
  • Learning Management System
  • Maintenance
  • Planning
  • Portfolio
  • Setup
  • Webdesign
  • WordPress

Verein 3.0 – WerteWissenWandel

Verein 3.0 is an e-Learning platform, that is meant to assist people in the creation of new clubs in Germany.… Read More

2 months ago
  • Development
  • PHP

PsySH – PHP Debug Console

A runtime developer console, interactive debugger and REPL for PHP. PsySH can be used as an interactive debugger, much like JavaScript's debugger… Read More

2 months ago
  • API
  • Deployment
  • Design
  • Development
  • Essentials
  • General
  • Hosting
  • Javascript
  • Node.js

Screenshot Service with Node.js

Manet is a REST API server which allows capturing screenshots of websites using various parameters. The Node.js server can use SlimerJS… Read More

2 months ago