• I have a need to be able to generate fake/virtual/dynamic pages based on a url like https://www.mycinema.com/wpcinema/movie/MOVIEID to be able to display movies for cinemas with info on the movie and live session feed information.

    After spending many hours researching, there doesn’t seem to be much stuff written on how to do virtual pages in WordPress, so I will be writing up my experiences after getting this resolved!

    So far, the current plan is to use the two filters – template_redirect to set the template to the current plugin’s page.php template, and the_content to insert the content. The idea is to use the theme’s template so the pages theme in well with the site.

    (I got this approach from this excellent 2012 page from Xavi Esteve).

    I have two problems:

    1. What is the best, most bullet proof, way to do this? Am I using the wrong approach? My thinking was that using the current theme’s template was likely to provide the best current fit for the style of the website.
    2. TwentyTwelve does not appear to be calling the the_content filter in the context I’m using it. I suspect I’m doing something wrong, but cannot find the problem. This is probably closely related to question 1. TwentyTwelve definitely calls the_content for a normal page, and even an early add_filter() doesn’t trigger in my code.

    I discovered get_template_part() yesterday and wondered if I should be using that instead of manually looking in the child folder then the parent and running an include (not shown in the code below).

    I wouldn’t be asking, but I’m at my wit’s end having googled extensively, possibly for the wrong search terms.

    I’ve considered custom post types, but there are various complexities around this (including content that may change every few minutes) which means a dynamically generated page works much better.

    This is an excerpt from the code I’ve written to explain the problem further:

    add_action('parse_request', array(&$this, 'vm_parse_request'));
    
    function vm_parse_request( &$wp )
    {
        global $wp;
        if (empty($wp->query_vars['pagename']))
            return; // page isn't permalink
    
        $p = $wp->query_vars['pagename'];
    
        if (! preg_match("#wp-cinema/movie/([^/]+)#", $p, $m))
            return;
    
        // setup hooks and filters to generate virtual movie page
        add_action('template_redirect', array(&$this, 'vm_template_redir'));
        add_filter('the_content', array(&$this, 'vm_the_content'));
    }
    
    function vm_template_redir()
    {
        // Reset currrently set 404 flag as this is a plugin-generated page
        global $wp_query;
        $wp_query->is_404 = false;
    
        $template = 'page.php';
    
        include(STYLESHEETPATH."/page.php"); // child
        // parent case left out for brevity
    
        exit;
    }
    
    function vm_the_content($content)
    {
        return "my new content (actually generated dynamically)";
    }

    This is going to be an increasingly common thing in WordPress – can anyone offer suggestions or help? Anything is much appreciated.

Viewing 7 replies - 1 through 7 (of 7 total)
  • Moderator bcworkz

    (@bcworkz)

    The problem is that there is no content corresponding to the requested page, so the theme’s loop never runs and thus ‘the_content’ filter never fires.

    My suggested approach is to create a custom page template which is copied to the theme folder on activation. (Unless you can create a page based on a template not in the theme folder?) A page (post type) is also entered into the DB based on this template as well. A rewrite rule is created to route any requests of the particular form to this page.

    This page template can grab the needed parameters from either query vars, URL parms placed by the rewrite rule, or by parsing the requested URL directly. From this data, the content is output. As a page template, all the theme styling, headers, footers, etc. will be incorporated.

    There is no doubt many possible approaches, this is just an idea that came immediately to mind.

    Thread Starter Brian Coogan

    (@brianoz)

    Thanks for your input, that’s really helpful.

    Is there a way to simulate content so the loop fires? I can probably research this on my own.

    I hate to alter a running theme, even a child theme, seems to violate various “keep it clean” principles.

    Moderator bcworkz

    (@bcworkz)

    You could make a dummy post via script that your movie data URL would point to. As long as the post name slug is at the end of the permalink, you can insert any arbitrary data in the URL before the slug (provided the parser doesn’t mistake it for something else – i.e. your URL should not contain the term “category”). Requesting this post will trigger ‘the_content’ filter. Your filter callback can then check if it was called for this dummy post, in which case, the initial content is discarded and new content is built based on other content in the URL.

    Moderator bcworkz

    (@bcworkz)

    I just came across another virtual page question FYI: https://www.ads-software.com/support/topic/virtual-page-within-theme-template?replies=1

    I will suggest the OP check here for ideas.

    BTW, it appears when you enter a Page post type via script, it’s template can reside anywhere by entering the proper path in postmeta under the key ‘_wp_page_template’. I haven’t actually tested this, but it does appear to be the case.

    It only needs to be in the theme folder to show up in the page template dropdown.

    Thread Starter Brian Coogan

    (@brianoz)

    I guess there are two parts to the actual task:

    1) ability to use a different template other than the page template, using template rules and child theme awareness.

    The solution to this appears to be the above code, replacing the include with a call to get_template_part().

    2) ability to fool the loop into running and outputting the_content.

    A solution to this seems to be achievable by using the_posts filter, at least I have a solution more or less working at the moment.

    At the moment I can’t see anything other than a hybridization of these two working.

    It looks like Scott Sherrill may have been the first to write about this originally in 2007 and multiple people have picked up that work, including the current clearest article I found:
    https://davejesch.com/wordpress/wordpress-tech/creating-virtual-pages-in-wordpress/

    A comment is displayed if $wp_query->current_comment is set to -1, the fix being to set it as shown to a null string.
    $wp_query->current_comment = ''; // -1 shows a comment sometimes??
    This behaviour is particularly weird as current_comment is usually -1 for a normal page!

    In any case, a combination of these two seems so far to be working, although it’s early days.

    IMO it would be nice to see WordPress stepping up to the mark and providing a simple interface for this, as it appears they are regularly breaking other options. Such an interface would provide ability to specify a template, content and title. This sort of functionality is required when items may not be reflected in the post structure, for instance, product pages, credit card acknowledgement pages, and many other page applications that may be completely dynamic. It seems like this is being requested regularly on stackoveflow and on here and nobody has been capable of providing any answer to nearly all the posts.

    Thanks to the generosity of bcworkz for providing some crucial clues to solving the issue!

    Thread Starter Brian Coogan

    (@brianoz)

    OK – as posted above, the solution of providing a dummy post via a filter for the_posts was the working solution I ended up with.

    I’ve documented this in full gory detail at:

    https://stackoverflow.com/questions/17960649/wordpress-plugin-generating-virtual-pages-and-using-theme-template

    I ended up using part of Xavi Esteve’s solution to allow me to trigger the virtual page as well as allowing the page template to be overridden.

    None of the solutions out there at the moment seem to work without warnings or errors; I suspect WordPress has evolved since they were originally published.

    found this very useful, and thought i’d add how to capture output as it came in useful to me

    https://stackoverflow.com/questions/171318/how-do-i-capture-php-output-into-a-variable

Viewing 7 replies - 1 through 7 (of 7 total)
  • The topic ‘Plugin generating virtual pages, issue with the_content not running’ is closed to new replies.