2013-07-31 39 views
12

Tôi cần có khả năng tạo trang giả/ảo/động dựa trên url như http://www.mycinema.com/wpcinema/movie/MOVIEID để có thể hiển thị phim cho rạp chiếu phim với thông tin về phim và nguồn cấp dữ liệu phiên trực tiếp thông tin.Plugin Wordpress tạo trang ảo và sử dụng mẫu chủ đề

Sau khi dành nhiều giờ nghiên cứu, dường như không có nhiều nội dung được viết về cách thực hiện các trang ảo trong WordPress, vì vậy tôi sẽ viết lên trải nghiệm của mình sau khi giải quyết xong!

Cho đến giờ, kế hoạch hiện tại là sử dụng hai bộ lọc - template_redirect để đặt mẫu thành mẫu page.php của plugin hiện tại và the_content để chèn nội dung. Ý tưởng là sử dụng mẫu của chủ đề để chủ đề trang cũng phù hợp với trang web.

(Tôi có cách tiếp cận này từ this excellent 2012 page from Xavi Esteve).

Tôi có hai vấn đề:

  1. là tốt nhất, hầu hết đạn bằng chứng, cách để làm điều này là gì? Tôi đang sử dụng phương pháp sai? Suy nghĩ của tôi là sử dụng mẫu của chủ đề hiện tại có khả năng cung cấp sự phù hợp hiện tại tốt nhất cho phong cách của trang web.

  2. TwentyTwelve dường như không gọi bộ lọc the_content trong ngữ cảnh tôi đang sử dụng. Tôi nghi ngờ tôi đang làm điều gì đó sai, nhưng không thể tìm thấy vấn đề. Điều này có lẽ liên quan chặt chẽ đến câu hỏi 1. TwentyTwelve chắc chắn gọi the_content cho một trang bình thường, và ngay cả một add_filter đầu() không kích hoạt trong mã của tôi.

Tôi phát hiện get_template_part() hôm qua và tự hỏi liệu tôi có nên sử dụng thay vì tìm kiếm thủ công trong thư mục con sau đó cha mẹ và chạy một bao gồm.

Tôi sẽ không hỏi, nhưng tôi đang ở phần cuối của tôi đã googled rộng rãi, có thể cho các cụm từ tìm kiếm sai.

Tôi đã xem xét các loại bài đăng tùy chỉnh, nhưng có nhiều sự phức tạp khác nhau (bao gồm nội dung có thể thay đổi sau vài phút) có nghĩa là trang được tạo động hoạt động tốt hơn nhiều.

Đây là một đoạn trích từ đoạn code tôi đã viết để giải thích các vấn đề nữa:

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)"; 
} 

này sẽ là một điều ngày càng phổ biến trong WordPress - ai cũng có thể cung cấp gợi ý hay giúp đỡ? Bất cứ điều gì được nhiều đánh giá cao.

+0

Hi Brian, tôi tự hỏi nếu tôi có thể áp dụng các trang ảo cho câu hỏi của tôi http: // wordpress .stackexchange.com/questions/110118/how-to-create-custom-home-page-qua-plugin bạn nghĩ sao? – Radek

+0

Radek - mặc dù tôi chưa thử nghiệm, tôi tin rằng bạn có thể, nếu bạn có thể đặt trang chủ thành một trang khác với Trang hiện có. Hoặc, bạn có thể sử dụng mã của tôi để ghi đè lên. –

Trả lời

10

(Cập nhật lúc chân của bài viết bao gồm liên kết đến cải thiện đang ý chính làm việc)

tôi muốn gửi một câu trả lời cho điều này vì nó dường như NONE của các truy vấn về WordPress trang ảo trên đây đã có câu trả lời! Và có rất nhiều máu liên quan đến việc nhận được câu trả lời cho điều này, kiểm tra nó và đảm bảo nó hoạt động tốt. Hy vọng rằng điều này sẽ tiết kiệm một vài người khác nỗi đau mà tôi đã trải qua ...

Hóa ra là vào năm 2013 với WordPress 3.5.2+ (hiện tại là 3.6 tuần trước), giải pháp từ Xavi Esteve đã đề cập ở trên không còn hoạt động , như WordPress đã phát triển, dangit.

Sử dụng phương pháp template_redirect ở trên, vấn đề là WordPress liên quan, không có nội dung trang/bài và do đó nhiều chủ đề sẽ không gọi the_content(), do đó mã của tôi trên bộ lọc the_content không bao giờ được gọi là.

Giải pháp tốt nhất hiện nay dường như là móc vào bộ lọc 'the_posts' và trả về một trang giả, tuy nhiên chính nó không có chủ đề gắn liền với nó.

Giải pháp cho việc thiếu chủ đề là kết hợp điều này với một phần của phương pháp Xavi Esteve để cho phép tôi thay đổi mẫu đang được sử dụng để tạo trang.

Cách tiếp cận này sẽ hoạt động ngay lập tức cho hầu hết, nếu không phải tất cả, chủ đề WordPress là mục tiêu của tôi và nó hoạt động thực sự tốt với các chủ đề tôi đã thử nghiệm cho đến nay.

tôi đã sử dụng phương pháp ghi nhận bởi Dave Jesch trên trang này (có các phiên bản khác của việc này, nhưng Dave là người duy nhất giải thích nó một cách cẩn thận, nhờ Dave!): http://davejesch.com/wordpress/wordpress-tech/creating-virtual-pages-in-wordpress/

Tôi cũng đã trải qua rất nhiều đau ở đây với phần bình luận Wordpress xuất hiện ở dưới cùng của trang trong một số chủ đề. Giải pháp cho điều này sẽ xuất hiện trong tệp được liên kết ở trên và có lẽ nằm ngoài phạm vi cho giải pháp cụ thể này.

Ngoài ra, để ngăn chặn một cảnh báo với WordPress 3.5.2+, tôi cũng đã thêm một thành viên post:

$post->ancestors = array(); 

Giải pháp này được sử dụng trong wp-điện ảnh WordPress plugin (tập tin views.php nếu bạn muốn để lấy một số mã làm việc, nên được kiểm tra trong vài tuần tới). Nếu có vấn đề với cách tiếp cận, tôi sẽ giữ tập tin đó hiện tại vì nó là một phần của một dự án lớn hơn.

Giải pháp làm việc đầy đủ bên dưới. Điều này được trích từ một đoạn mã dài hơn nhiều, điều này cũng ngăn cản các bình luận xuất hiện vv (xem liên kết được cung cấp ở trên). Mã số:

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; 
} 

Bằng cách này, điều quan trọng là phải nói rằng điều này khá là hack và rất muốn biết cách thực hiện tốt hơn. Ngoài ra, tôi rất muốn nhìn thấy WordPress bước lên đến nhãn hiệu và cung cấp một API để tạo ra các trang giả mạo. (Tôi nghi ngờ họ có lý do ý thức hệ tại sao họ không làm vậy, nhưng sẽ tốt hơn nếu xem giải pháp của họ cho điều này, ngay cả khi thay thế, được giải thích sâu); Cá nhân tôi cảm thấy có những trường hợp tôi không muốn can thiệp vào trang web của người dùng chỉ để tạo trang.

CẬP NHẬT Tháng 2 năm 2014: Tôi đã trừu tượng hóa này vào một lớp học mà nên cung cấp đầy đủ tính linh hoạt cho hầu hết các ứng dụng: https://gist.github.com/brianoz/9105004

+0

Tôi đã biến điều này thành một lớp để quản lý nhiều trang ảo. Lớp này gọi ra một hàm nội dung được cung cấp khi một regexp được kết hợp. Khi tôi cảm thấy vững chắc về điều này, tôi sẽ thay thế liên kết ở trên bằng một liên kết đến tệp lớp (trong đó bao gồm một ví dụ). Prod tôi nếu bạn cần nó và tôi đã quên! :) –

+0

Đây là một phương pháp thú vị. Tôi đã cố gắng làm một cái gì đó tương tự trong một thời gian để vừa phải thành công. Bạn có liên kết đến tệp lớp bạn đang cung cấp không? –

+0

Xin lỗi, có; Tôi quên tôi đã làm nó rồi.Gist là ở đây (cập nhật bài báo cũng): https://gist.github.com/brianoz/9105004 Điều này nên đủ linh hoạt để làm việc với hầu hết các ứng dụng, phản hồi được đánh giá cao. –

Các vấn đề liên quan