Auto insert More tags in all posts

I have a theme for my mobile site that requires the <!--more--> tag in my posts for it to display an excerpt of my post’s content.

I’ve got over 2000 posts already, and its going to take forever to add the tag in all my posts. I don’t want to use a plugin, cause I’ve used one that wasn’t stable at all.

Read More

I just need a snippet I can hook up in my theme’s files that will add the more tag after a specific character or word count in all my posts, and in every post I publish after that.

Related posts

2 comments

  1. If you want to control the string count, then you can do it by the following.

    Put the below code in the active theme’s functions.php file:–

    function custom_excerpt_length( $length ) {
        return 20; // You can change the number here as per your need.
    }
    add_filter( 'excerpt_length', 'custom_excerpt_length', 999 );
    

    By default, excerpt length is set to 55 words. To change excerpt
    length to 20 words using excerpt_length filter, add the above code
    to functions.php file in your theme:

    For more details check the Codex

  2. The Read More (<!--more-->) tag is processed by get_the_content() in wp-includes/post-template.php. It does not run any hookable filters on its content input; however, that comes from the $pages global which can be modified at the time it is set up by hooking the the_post action.

    The following function will auto-insert a <!--more--> tag at the first space after 280 characters (skipping HTML tags, and counting sequences of whitespace as a single character), if there isn’t one already present:

    add_action(
      'the_post',
      function($post, $query) {
        global $pages, $shortcode_tags;
        // Matches an HTML entity, block of whitespace, or single character:
        static $rxChar = '&#?+\w++;|\s++|[^<]';
        // Matches an HTML tag:
        static $rxTag = '<[^>]*+>';
        // Based on regex in from `get_shortcode_regex`
        $tagnames = array_keys($shortcode_tags);
        $tagregexp = join('|', array_map('preg_quote', $tagnames));
        $rxShortcode =
          '\['                 // Opening bracket
          . '\[?+'             // 1: Optional second opening bracket for escaping
          . '(?&shortcode_tag)' // 2: Shortcode name
          . '(?![\w-])'        // Not followed by word character or hyphen
          . '[^\]\/]*+'       // Not a closing bracket or forward slash
          . '(?:'
          .   '\/(?!\])'      // A forward slash not followed by a closing bracket
          .   '[^\]\/]*+'     // Not a closing bracket or forward slash
          . ')*+'
          . '\/?+'             // 4: Self closing tag ...
          . '\]'               // ... and closing bracket
          . '\]?+';            // 6: Optional second closing brocket for escaping
        // Matches zero or more HTML tags or shortcode tags
        $rxTags = "(?:$rxTag|$rxShortcode)*+";
        $regex = "/(?(DEFINE)(?<shortcode_tag>$tagregexp)(?<char>$rxChar)"
          . "(?<tags>$rxTags))"
          // At least 280 characters, from the start, followed by a space
          // (catastrophic failure with general repetition quantifier mitigated
          // against by splitting into two multiplicative repetitions):
          . '^(?:(?:(?&tags)(?&char)){10}+){28}+(?&tags)(?:(?&char)(?&tags))*?'
          . '(?=\s)/u';
        foreach ($pages as $i => $page) {
          if (strpos($page, '<!--more') === false) {
            $page = preg_replace($regex, '$0<!--more-->', $page, 1);
            if ($page !== null) {
              $pages[$i] = $page;
            } else {
              trigger_error(
                "Regex failure inserting 'Read More' tag into `$pages[$i]`."
              );
            }
          }
        }
      },
      10, 2
    );
    

    It should be fairly self-explanatory, though I’ll add a few notes on the regex:

    • The u (UTF-8) modifier ensures that multibyte characters count only
      as one.
    • The + (possessive) quantifier massively optimizes the
      performance and memory footprint
      (where the token can’t consume any
      of the following token). However, it doesn’t seem to make much difference
      mitigating against failure when applied to the general repetition quantifier,
      so this has been split into repetitions of repetitions. And nonetheless, in
      the event of failure the content will be left unchanged.
    • The ? (lazy) quantifier ensures the first
      space after 280 characters is stopped at, not the last.

    (I know this question was asked more than 4 years ago, but it hadn’t been answered; I found it looking for a solution for exactly the same, which I did not find elsewhere.)

Comments are closed.