Bri*_*n C 12 wordpress virtual plugins templates themes
我需要能够基于像http://www.mycinema.com/wpcinema/movie/MOVIEID这样的网址生成虚假/虚拟/动态页面,以便能够显示电影中的电影以及有关电影和直播的信息会话提要信息.
在花了很多时间研究之后,似乎没有太多关于如何在WordPress中编写虚拟页面的内容,所以我会在解决之后写下我的经验!
到目前为止,目前的计划是使用两个过滤器 - template_redirect将模板设置为当前插件的page.php模板,并使用the_content来插入内容.我们的想法是使用主题的模板,使页面主题与网站一致.
(我从Xavi Esteve的这个优秀的2012年页面获得了这种方法).
我有两个问题:
这样做的最好,最防弹的方法是什么?我使用了错误的方法吗?我的想法是,使用当前主题的模板可能会提供最适合网站风格的模板.
TwentyTwelve似乎没有在我正在使用它的上下文中调用the_content过滤器.我怀疑我做错了什么,但找不到问题.这可能与问题1密切相关.TinntyTwelve肯定会调用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)";
}
Run Code Online (Sandbox Code Playgroud)
这在WordPress中将变得越来越普遍 - 任何人都可以提供建议或帮助吗?任何事都非常感激.
Bri*_*n C 11
(在改进工作代码要点的链接的文章的脚下更新)
我想发布一个答案,因为似乎没有关于WordPress虚拟页面的查询有答案!获得这个问题的答案有很多血,测试它并确保它运作良好.希望这能为我的其他几个人带来痛苦......
事实证明,在2013年使用WordPress 3.5.2+(现在是一周前的3.6),上面提到的Xavi Esteve的解决方案不再适用,因为WordPress已经发展,但是.
上面使用上面的template_redirect方法,问题在于,就WordPress而言,没有页面/帖子内容,因此许多主题不会调用the_content(),因此我的on_content过滤器上的代码永远不会被调用.
现在最好的解决方案似乎是挂钩'the_posts'过滤器并返回一个伪页面,但是它本身并没有附加主题.
缺乏主题的解决方案是将其与Xavi Esteve方法的一部分混合,以允许我更改用于生成页面的模板.
这种方法应该立即对大多数(如果不是全部)WordPress主题起作用,这是我的目标,并且它与我到目前为止测试的主题非常有效.
我在这个页面上使用了Dave Jesch记录的方法(还有其他版本,但Dave是唯一一个仔细解释它的人,感谢Dave!):http://davejesch.com/wordpress/wordpress-tech/creating -虚拟的页面功能于WordPress的/
我在这里也遇到了很多痛苦,在一些主题中出现在页面底部的Wordpress评论部分.此解决方案将出现在上面链接的文件中,可能超出此特定解决方案的范围.
另外,为了防止使用WordPress 3.5.2+发出警告,我还必须添加帖子成员:
$post->ancestors = array();
Run Code Online (Sandbox Code Playgroud)
此解决方案用于wp-cinema WordPress插件(文件views.php,如果你想获取一些工作代码,应该在接下来的几周内检查).如果该方法存在问题,我将保持该文件的最新状态,因为它是较大项目的一部分.
完整的工作解决方案如下.这是从更长的代码段中摘录的,这也防止了注释出现等(参见上面提供的链接).代码:
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;
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,重要的是要说我觉得这几乎是一个黑客,并且很想知道如何做得更好.此外,我很高兴看到WordPress升级到标记并提供用于生成虚假页面的API.(我怀疑他们有意识形态的原因,为什么他们不会,但是很高兴看到他们的解决方案,即使替代方案,深入解释); 我个人觉得有些情况下我不想干涉用户的网站只是为了生成页面.
更新2014年2月:我已经将它抽象为一个类,它应该为大多数应用程序提供足够的灵活性:https://gist.github.com/brianoz/9105004
| 归档时间: |
|
| 查看次数: |
9054 次 |
| 最近记录: |