Ich muss in der Lage sein, gefälschte/virtuelle/dynamische Seiten basierend auf einer URL wie zu generieren http://www.mycinema.com/wpcinema/movie/MOVIEID Filme für Kinos mit Informationen zum Film und Live-Session-Feed-Informationen anzeigen zu können.
Nachdem ich viele Stunden mit der Recherche verbracht habe, scheint nicht viel darüber geschrieben zu sein, wie man virtuelle Seiten in WordPress erstellt, also werde ich meine Erfahrungen aufschreiben, nachdem ich das gelöst habe!
Bisher ist geplant, die beiden Filter zu verwenden – template_redirect, um das Template auf das page.php-Template des aktuellen Plugins zu setzen, und the_content, um den Inhalt einzufügen. Die Idee ist, die Vorlage des Themas zu verwenden, damit sich das Seitenthema gut in die Website einfügt.
(Ich habe diesen Ansatz von diese ausgezeichnete 2012-Seite von Xavi Esteve).
Ich habe zwei Probleme:
-
Was ist der beste und kugelsicherste Weg, dies zu tun? Verwende ich den falschen Ansatz? Mein Gedanke war, dass die Verwendung der Vorlage des aktuellen Themas wahrscheinlich die beste aktuelle Passform für den Stil der Website bietet.
-
TwentyTwelve scheint den Filter the_content nicht in dem Kontext aufzurufen, in dem ich ihn verwende. Ich vermute, dass ich etwas falsch mache, aber ich kann den Fehler nicht finden. Dies hängt wahrscheinlich eng mit Frage 1 zusammen. TwentyTwelve ruft definitiv the_content für eine normale Seite auf, und selbst ein frühes add_filter() löst in meinem Code nicht aus.
Ich habe gestern get_template_part() entdeckt und mich gefragt, ob ich das verwenden sollte, anstatt manuell im untergeordneten Ordner und dann im übergeordneten Ordner zu suchen und ein Include auszuführen.
Ich würde nicht fragen, aber ich bin mit meinem Latein am Ende, nachdem ich ausgiebig gegoogelt habe, möglicherweise nach den falschen Suchbegriffen.
Ich habe benutzerdefinierte Beitragstypen in Betracht gezogen, aber es gibt verschiedene Komplexitäten (einschließlich Inhalt, der sich alle paar Minuten ändern kann), was bedeutet, dass eine dynamisch generierte Seite viel besser funktioniert.
Dies ist ein Auszug aus dem Code, den ich geschrieben habe, um das Problem weiter zu erklären:
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)";
}
Dies wird in WordPress immer häufiger vorkommen – kann jemand Vorschläge machen oder helfen? Alles wird sehr geschätzt.
(Update am Fuß des Artikels, einschließlich Link zu verbessertem Arbeitscode-Kern)
Ich wollte eine Antwort darauf posten, da anscheinend KEINE der Fragen zu virtuellen WordPress-Seiten hier Antworten hatte! Und es war viel Blut im Spiel, um die Antwort auf diese Frage zu finden, sie zu testen und sicherzustellen, dass sie gut funktioniert. Hoffentlich erspart das ein paar anderen den Schmerz, den ich durchgemacht habe …
Es stellt sich heraus, dass im Jahr 2013 mit WordPress 3.5.2+ (jetzt 3.6 seit einer Woche) die oben erwähnte Lösung von Xavi Esteve nicht mehr funktioniert, da sich WordPress weiterentwickelt hat, verdammt.
Wenn man die Methode template_redirect oben allein verwendet, besteht das Problem darin, dass es für WordPress keinen Seiten-/Beitragsinhalt gibt und daher viele Themen the_content() nicht aufrufen werden, daher wird mein Code für den the_content-Filter nie aufgerufen.
Heutzutage scheint die beste Lösung zu sein, sich in den ‘the_posts’-Filter einzuklinken und eine Pseudo-Seite zurückzugeben, die jedoch an sich kein Thema hat.
Die Lösung für das fehlende Thema bestand darin, dies mit einem Teil von Xavi Esteves Ansatz zu kombinieren, um mir zu ermöglichen, die Vorlage zu ändern, die zum Erstellen der Seite verwendet wird.
Dieser Ansatz sollte für die meisten, wenn nicht alle WordPress-Themen sofort funktionieren, was mein Ziel war, und es funktioniert wirklich gut mit den Themen, die ich bisher getestet habe.
Ich habe den von Dave Jesch auf dieser Seite dokumentierten Ansatz verwendet (es gibt andere Versionen davon, aber Dave ist der einzige, der es sorgfältig erklärt hat, danke Dave!): http://davejesch.com/wordpress/wordpress-tech/creating-virtual-pages-in-wordpress/
Ich habe hier auch viel Schmerz durchgemacht, da der Abschnitt mit den Kommentaren von WordPress in einigen Themen unten auf der Seite angezeigt wurde. Die Lösung dafür wird in der oben verlinkten Datei erscheinen und ist wahrscheinlich nicht im Umfang dieser speziellen Lösung enthalten.
Um eine Warnung mit WordPress 3.5.2+ zu verhindern, musste ich auch ein Beitragsmitglied hinzufügen:
$post->ancestors = array();
Diese Lösung wird im wp-cinema WordPress-Plugin (file Ansichten.php wenn Sie sich etwas funktionierenden Code schnappen möchten, sollte in den nächsten Wochen eingecheckt werden). Wenn es Probleme mit dem Ansatz gibt, werde ich diese Datei aktuell halten, da sie Teil eines größeren Projekts ist.
Die vollständige Arbeitslösung ist unten. Dies ist ein Auszug aus einem viel längeren Codestück, das auch das Erscheinen von Kommentaren usw. verhindert (siehe oben angegebenen Link). Der Code:
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("https://stackoverflow.com/" . $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;
}
Übrigens ist es wichtig zu sagen, dass ich das Gefühl habe, dass dies ein ziemlicher Hack ist, und ich würde gerne wissen, wie es besser gemacht werden könnte. Außerdem würde ich gerne sehen, wie WordPress ins Schwarze trifft und eine API zum Generieren gefälschter Seiten bereitstellt. (Ich vermute, sie haben ideologische Gründe, warum sie es nicht tun, aber es wäre schön, ihre Lösungen dafür, auch wenn sie alternativ sind, ausführlich erklärt zu sehen); Ich persönlich habe das Gefühl, dass es Fälle gibt, in denen ich mich nicht in die Site eines Benutzers einmischen möchte, nur um Seiten zu generieren.
UPDATE Februar 2014: Ich habe dies in eine Klasse abstrahiert, die für die meisten Anwendungen ausreichende Flexibilität bieten sollte: https://gist.github.com/brianoz/9105004
Hallo Brian, ich frage mich, ob ich virtuelle Seiten auf meine Frage anwenden kann wordpress.stackexchange.com/questions/110118/… Was denken Sie?
– Radek
15. August 2013 um 6:26 Uhr
Radek – obwohl ich es nicht getestet habe, glaube ich, dass Sie es könnten, wenn Sie die Startseite auf etwas anderes als eine vorhandene Seite einstellen können. Oder Sie könnten meinen Code verwenden, um ihn zu überschreiben.
– Brian C
20. Februar 2014 um 1:17 Uhr