gpt4 book ai didi

Wordpress 插件生成虚拟页面并使用主题模板

转载 作者:行者123 更新时间:2023-12-04 01:02:35 25 4
gpt4 key购买 nike

我需要能够基于像 http://www.mycinema.com/wpcinema/movie/MOVIEID 这样的 url 生成假/虚拟/动态页面。能够显示带有电影信息和现场 session 提要信息的电影院电影。

在花了很多时间研究之后,似乎没有太多关于如何在 WordPress 中创建虚拟页面的内容,所以我会在解决这个问题后写下我的经验!

到目前为止,目前的计划是使用两个过滤器——template_redirect 将模板设置为当前插件的 page.php 模板,以及 the_content 插入内容。这个想法是使用主题的模板,使页面主题与站点完美融合。

(我从 this excellent 2012 page from Xavi Esteve 得到了这种方法)。

我有两个问题:

  • 什么是最好的,最防弹的方法来做到这一点?我使用了错误的方法吗?我的想法是使用当前主题的模板可能会提供最适合网站风格的当前模板。
  • 在我使用的上下文中,TwentyTwelve 似乎没有调用 the_content 过滤器。我怀疑我做错了什么,但找不到问题。这可能与问题 1 密切相关。TwentyTwelve 肯定会为普通页面调用 the_content,甚至早期的 add_filter() 也不会在我的代码中触发。

  • 我昨天发现了 get_template_part() 并想知道我是否应该使用它而不是手动查看子文件夹然后是父文件夹并运行包含。

    我不会问,但我已经在谷歌上进行了广泛的搜索,可能是错误的搜索词。

    我已经考虑过自定义帖子类型,但围绕这有各种复杂性(包括可能每隔几分钟更改的内容),这意味着动态生成的页面效果更好。

    这是我为进一步解释问题而编写的代码的摘录:
    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)";
    }

    这将成为 WordPress 中越来越普遍的事情 - 任何人都可以提供建议或帮助吗?任何东西都非常感谢。

    最佳答案

    (在文章底部更新,包括指向改进的工作代码要点的链接)

    我想发布一个答案,因为似乎这里关于 WordPress 虚拟页面的查询都没有答案!为了得到这个问题的答案、测试它并确保它运行良好,需要付出很多努力。希望这能拯救其他一些人我所经历的痛苦......

    事实证明,在 2013 年使用 WordPress 3.5.2+(一周前现在是 3.6)时,上面提到的 Xavi Esteve 的解决方案不再有效,因为 WordPress 已经发展,dangit。

    单独使用上面的 template_redirect 方法,问题在于就 WordPress 而言,没有页面/帖子内容,因此许多主题不会调用 the_content(),因此我在 the_content 过滤器上的代码永远不会被调用。

    现在最好的解决方案似乎是连接到“the_posts”过滤器并返回一个伪页面,但是它本身没有附加主题。

    缺少主题的解决方案是将其与 Xavi Esteve 的部分方法混合,以允许我更改用于生成页面的模板。

    这种方法应该立即适用于大多数(如果不是全部)WordPress 主题,这是我的目标,并且它与我迄今为止测试过的主题非常配合。

    我使用了 Dave Jesch 在此页面上记录的方法(还有其他版本,但 Dave 是唯一一个仔细解释的人,感谢 Dave!):http://davejesch.com/wordpress/wordpress-tech/creating-virtual-pages-in-wordpress/

    我也在这里经历了很多痛苦,Wordpress 评论部分出现在某些主题的页面底部。此问题的解决方案将出现在上面链接的文件中,并且可能超出了此特定解决方案的范围。

    另外,为了防止 WordPress 3.5.2+ 出现警告,我还必须添加一个帖子成员:

     $post->ancestors = array();

    这个解决方案用于 wp-cinema WordPress 插件(文件 views.php 如果你想获取一些工作代码,应该在接下来的几周内 checkin )。如果该方法存在问题,我将保持该文件的最新状态,因为它是更大项目的一部分。

    完整的工作解决方案如下。这是从一段更长的代码中摘录的,该代码段还可以防止出现注释等(请参阅上面提供的链接)。编码:
    add_action('parse_request', 'vm_parse_request');


    // Check page requests for Virtual movie pages
    // If we have one, generate 'movie details' Virtual page.
    // ...
    //
    function vm_parse_request(&$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', 'vm_template_redir');

    $this->vm_body = "page body text";

    add_filter('the_posts', 'vm_createdummypost');

    // now that we know it's my page,
    // prevent shortcode content from having spurious <p> and <br> added
    remove_filter('the_content', 'wpautop');
    }


    // Setup a dummy post/page
    // From the WP view, a post == a page
    //
    function vm_createdummypost($posts)
    {
    // have to create a dummy post as otherwise many templates
    // don't call the_content filter
    global $wp, $wp_query;

    //create a fake post intance
    $p = new stdClass;
    // fill $p with everything a page in the database would have
    $p->ID = -1;
    $p->post_author = 1;
    $p->post_date = current_time('mysql');
    $p->post_date_gmt = current_time('mysql', $gmt = 1);
    $p->post_content = $this->vm_body;
    $p->post_title = $this->vm_title;
    $p->post_excerpt = '';
    $p->post_status = 'publish';
    $p->ping_status = 'closed';
    $p->post_password = '';
    $p->post_name = 'movie_details'; // slug
    $p->to_ping = '';
    $p->pinged = '';
    $p->modified = $p->post_date;
    $p->modified_gmt = $p->post_date_gmt;
    $p->post_content_filtered = '';
    $p->post_parent = 0;
    $p->guid = get_home_url('/' . $p->post_name); // use url instead?
    $p->menu_order = 0;
    $p->post_type = 'page';
    $p->post_mime_type = '';
    $p->comment_status = 'closed';
    $p->comment_count = 0;
    $p->filter = 'raw';
    $p->ancestors = array(); // 3.6

    // reset wp_query properties to simulate a found page
    $wp_query->is_page = TRUE;
    $wp_query->is_singular = TRUE;
    $wp_query->is_home = FALSE;
    $wp_query->is_archive = FALSE;
    $wp_query->is_category = FALSE;
    unset($wp_query->query['error']);
    $wp->query = array();
    $wp_query->query_vars['error'] = '';
    $wp_query->is_404 = FALSE;

    $wp_query->current_post = $p->ID;
    $wp_query->found_posts = 1;
    $wp_query->post_count = 1;
    $wp_query->comment_count = 0;
    // -1 for current_comment displays comment if not logged in!
    $wp_query->current_comment = null;
    $wp_query->is_singular = 1;

    $wp_query->post = $p;
    $wp_query->posts = array($p);
    $wp_query->queried_object = $p;
    $wp_query->queried_object_id = $p->ID;
    $wp_query->current_post = $p->ID;
    $wp_query->post_count = 1;

    return array($p);
    }


    // Virtual Movie page - tell wordpress we are using the page.php
    // template if it exists (it normally will).
    //
    // We use the theme page.php if we possibly can; if not, we do our best.
    // The get_template_part() call will use child theme template if it exists.
    // This gets called before any output to browser
    //
    function vm_template_redir()
    {
    // Display movie template using WordPress' internal precedence
    // ie: child > parent; page-movie.php > page.php
    // this call includes the template which outputs the content
    get_template_part('page', 'movie');

    exit;
    }

    顺便说一句,重要的是要说我觉得这几乎是一种黑客行为,并且很想知道如何做得更好。此外,我很乐意看到 WordPress 达到标准并提供用于生成假页面的 API。 (我怀疑他们有意识形态的原因为什么他们不会,但很高兴看到他们对此的解决方案,即使有替代方案,深入解释);我个人觉得有些情况下我不想为了生成页面而去干预用户的网站。

    2014 年 2 月更新:我把它抽象成一个类,它应该为大多数应用程序提供足够的灵活性: https://gist.github.com/brianoz/9105004

    关于Wordpress 插件生成虚拟页面并使用主题模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17960649/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com