आप वर्डप्रेस में एक "वर्चुअल" पेज कैसे बनाते हैं


52

मैं वर्डप्रेस में एक कस्टम एपीआई एंडपॉइंट बनाने की कोशिश कर रहा हूं, और मुझे वर्डप्रेस की जड़ में एक वर्चुअल पेज पर एक वास्तविक पेज पर रिडायरेक्ट करने की जरूरत है जो मेरे प्लग-इन के साथ जहाज करता है। इसलिए मूल रूप से, एक पेज के सभी अनुरोध वास्तव में दूसरे को रूट किए जाते हैं।

उदाहरण:
http://mysite.com/my-api.php=>http://mysite.com/wp-content/plugins/my-plugin/my-api.php

इसका मतलब यह है कि एपीआई एंडपॉइंट के लिए url को जितना संभव हो उतना छोटा बनाया जाए (इसके http://mysite.com/xmlrpc.phpलिए वास्तविक एपीआई एंडपॉइंट फाइल को प्लग-इन के साथ शिप करने के बजाय उपयोगकर्ता को उनकी स्थापना और / या हैक कोर में फ़ाइलों को स्थानांतरित करने की आवश्यकता होती है। ।

मेरा पहला छुरा एक कस्टम पुनर्लेखन नियम जोड़ना था। हालाँकि, यह दो समस्याएं थीं।

  1. समापन बिंदु में हमेशा एक अनुगामी स्लेश होता था। यह बन गयाhttp://mysite.com/my-api.php/
  2. मेरा पुनर्लेखन नियम केवल आंशिक रूप से लागू किया गया था। यह करने के लिए पुनर्निर्देशित नहीं होगा wp-content/plugins..., यह करने के लिए पुनर्निर्देशित करेगा index.php&wp-content/plugins...। इसके कारण WordPress को या तो एक पृष्ठ प्रदर्शित होता है, जिसमें त्रुटि नहीं मिली है या केवल मुखपृष्ठ के लिए डिफ़ॉल्ट है।

विचार? सुझाव?

जवाबों:


55

वर्डप्रेस में दो प्रकार के पुनर्लेखन नियम हैं: आंतरिक नियम (डेटाबेस में संग्रहीत और WP :: parse_request () ), और बाहरी नियम ( .htaccessअपाचे द्वारा संग्रहीत और पार्स किए गए) द्वारा पार्स किए गए। आप किसी भी तरह से चुन सकते हैं, इस पर निर्भर करता है कि आपको अपनी फ़ाइल में वर्डप्रेस की कितनी आवश्यकता है।

बाहरी नियम:

बाहरी नियम स्थापित करना और पालन करना सबसे आसान है। यह my-api.phpवर्डप्रेस से कुछ भी लोड किए बिना, आपके प्लगइन निर्देशिका में निष्पादित करेगा ।

add_action( 'init', 'wpse9870_init_external' );
function wpse9870_init_external()
{
    global $wp_rewrite;
    $plugin_url = plugins_url( 'my-api.php', __FILE__ );
    $plugin_url = substr( $plugin_url, strlen( home_url() ) + 1 );
    // The pattern is prefixed with '^'
    // The substitution is prefixed with the "home root", at least a '/'
    // This is equivalent to appending it to `non_wp_rules`
    $wp_rewrite->add_external_rule( 'my-api.php$', $plugin_url );
}

आंतरिक नियम:

आंतरिक नियम को कुछ और काम करने की आवश्यकता है: पहले हम एक पुनर्लेखन नियम जोड़ते हैं जो एक क्वेरी संस्करण जोड़ता है, फिर हम इस क्वेरी को सार्वजनिक बनाते हैं, और फिर हमें इस प्लगइन के नियंत्रण को पास करने के लिए इस क्वेरी संस्करण के अस्तित्व की जांच करनी होगी। जब तक हम ऐसा करते हैं, तब तक सामान्य वर्डप्रेस इनिशियलाइज़ेशन हो चुका होता है (हम नियमित पोस्ट क्वेरी से ठीक पहले टूट जाते हैं)।

add_action( 'init', 'wpse9870_init_internal' );
function wpse9870_init_internal()
{
    add_rewrite_rule( 'my-api.php$', 'index.php?wpse9870_api=1', 'top' );
}

add_filter( 'query_vars', 'wpse9870_query_vars' );
function wpse9870_query_vars( $query_vars )
{
    $query_vars[] = 'wpse9870_api';
    return $query_vars;
}

add_action( 'parse_request', 'wpse9870_parse_request' );
function wpse9870_parse_request( &$wp )
{
    if ( array_key_exists( 'wpse9870_api', $wp->query_vars ) ) {
        include 'my-api.php';
        exit();
    }
    return;
}

3
मैं सिर्फ इतना कहना चाहता हूं कि इसके महत्वपूर्ण लिंक Permalinks पेज पर जाएं और WP-Admin में "Save Changes" पर क्लिक करें। मैं सोचने से पहले एक घंटे के लिए इस के साथ खेल रहा था कि मुझे पर्मलिंक्स को ताज़ा करने की ज़रूरत थी ... जब तक किसी को एक फ़ंक्शन नहीं पता है जो ऐसा कर सकता है?
एथानिल

बाहरी नियम के लिए: क्योंकि मेरे वेब रूट के लिए एक व्हाट्सएप चरित्र था, इस कारण अपाचे गिर गया। यदि आपके वर्डप्रेस इंस्टॉलेशन के रास्ते में मौजूद हैं तो व्हाट्सएप को बचना होगा।
विलस्टर

1
काम करता है, लेकिन मैं get_query_vars()अपने api.php के साथ किसी भी पारित क्वेरी चर का उपयोग करने के लिए प्रतीत नहीं कर सकता । मैंने जाँच की कि चर क्या हैं। और जो एकमात्र var सेट किया गया है, उसे aa WP objectकहा जाता है $wp। मैं इसे किसी WP_Queryऑब्जेक्ट में कैसे एक्सेस या ट्रांसफॉर्म कर सकता हूं ताकि मैं पास किए गए वेरिएबल को एक्सेस कर सकूं get_query_vars()?
जूल्स

1
@ जूल्स: जब आप includeकोई फ़ाइल बनाते हैं , तो वह वर्तमान दायरे में निष्पादित हो जाती है। इस मामले में, यह wpse9870_parse_requestफ़ंक्शन है, जिसमें केवल $wpपैरामीटर है। यह संभव है कि $wp_queryइस समय वैश्विक ऑब्जेक्ट सेट नहीं किया गया है, इसलिए get_query_var()यह काम नहीं करेगा। हालांकि, आप भाग्यशाली हैं: $wpवह वर्ग है जिसमें वह query_varsसदस्य होता है जिसकी आपको आवश्यकता होती है - मैं इसका उपयोग उपरोक्त कोड में स्वयं करता हूं।
Jan Fabry

1
एक बाहरी पुनर्लेखन नियम बनाने की कोशिश कर रहा है। अपनी मुट्ठी का टुकड़ा जोड़ा, लेकिन मुझे अभी भी 404 मिल रहा है। btw: फिर से लिखना नियम
सिसिर

12

इसने मेरे लिए काम किया। मैं कभी भी फिर से लिखने वाले एपीआई को नहीं छूता हूं, लेकिन हमेशा खुद को नई दिशाओं में धकेलने के लिए तैयार हूं। निम्नलिखित ने स्थानीय टेस्टहोस्ट के उप फ़ोल्डर में स्थित 3.0 के लिए मेरे परीक्षण सर्वर पर काम किया। मैं किसी भी मुद्दे को देखने के लिए नहीं है अगर वर्डप्रेस वेब रूट में स्थापित है।

बस इस कोड को एक प्लगइन में छोड़ दें और "taco-kittens.php" नाम की फ़ाइल को सीधे प्लग इन फ़ोल्डर में अपलोड करें। आपको अपने पर्मलिंक्स के लिए एक हार्ड फ्लश लिखना होगा। मुझे लगता है कि वे ऐसा करने के लिए सबसे अच्छा समय कहते हैं, यह सक्रियण प्लगइन पर है।

function taco_kitten_rewrite() {
    $url = str_replace( trailingslashit( site_url() ), '', plugins_url( '/taco-kittens.php', __FILE__ ) );
    add_rewrite_rule( 'taco-kittens\\.php$', $url, 'top' );
}
add_action( 'wp_loaded', 'taco_kitten_rewrite' );

शुभकामनाएं, -माइक


1
मुझे इस कोड को आज़माते समय एक पहुँच अस्वीकृत मिली। मुझे संदेह है कि मेरे सर्वर या WP को पूर्ण URL पसंद नहीं आया। दूसरी ओर, इसने ठीक काम किया:add_rewrite_rule( 'taco-kittens', 'wp-content/plugins/taco-kittens.php', 'top' );
जूल्स

क्या आप कृपया मुझे बता सकते हैं, मुझे टैको-किटेन्स में डाल देना चाहिए। एफपी, मुझे .htaccess या url rewrite का ज्ञान नहीं है।
प्रफुल्ल कुमार साहू

9

इसके बजाय ऐसा कुछ करने का कोई कारण नहीं?

http://mysite.com/?my-api=1

फिर बस अपने प्लगइन को 'इनिट' में हुक करें और उस वेरिएबल को चेक करें। यदि यह मौजूद है, तो वह करें जो आपके प्लगइन को करना और मरना है ()


5
यह काम करेगा, लेकिन मैं क्वेरी चर और वास्तविक समापन बिंदु के बीच एक बहुत स्पष्ट अंतर प्रदान करने की कोशिश कर रहा हूं। भविष्य में अन्य क्वेरी आ सकती हैं, और मैं नहीं चाहता कि उपयोगकर्ता चीजों को मिलाएं।
एमान

क्या होगा यदि आप फिर से लिखते हैं, लेकिन इसे GET var में फिर से लिखा है? आप यह भी देख सकते हैं कि कैसे पुन: लिखने के लिए robots.txt काम करता है। यह आपको यह पता लगाने में मदद कर सकता है कि मेरे-एपी / एफपी /
विल एंडरसन

यह सही समाधान है अगर आप एपीआई कॉल जैसे रोबोटों की परवाह नहीं करते हैं।
beytarovski

4

मैं आपको प्रश्नों को पूरी तरह से समझ नहीं पा रहा हूं, लेकिन क्या एक साधारण शोर्ट आपके मुद्दे को हल करेगा?

कदम:

  1. क्या ग्राहक एक पेज बनाते हैं अर्थात http://mysite.com/my-api
  2. क्या ग्राहक उस पृष्ठ में एक शोर्ट जोड़ सकता है, यानी [my-api-शोर्ट]

नया पृष्ठ API अंत बिंदु के रूप में कार्य करता है और आपका शोर्ट http://mysite.com/wp-content/plugins/my-plugin/my-api.php में आपके प्लगइन कोड के लिए अनुरोध भेजता है

(बेशक इसका मतलब यह है कि my-api.php में परिभाषित शोर्ट होगा)

आप शायद प्लगइन के माध्यम से चरण 1 और 2 को स्वचालित कर सकते हैं।


1

मैंने इसे फिर से लिखने के साथ निपटाया नहीं है, फिर भी, यह शायद थोड़ा कठिन है, लेकिन यह काम करने लगता है:

function api_rewrite($wp_rewrite) {
    $wp_rewrite->non_wp_rules['my-api\.php'] = 'wp-content/plugins/my-plugin/my-api.php';
    file_put_contents(ABSPATH.'.htaccess', $wp_rewrite->mod_rewrite_rules() );
}

यह काम करता है यदि आप इसे 'generate_rewrite_rules' में हुक करते हैं, लेकिन एक बेहतर तरीका होना चाहिए, क्योंकि आप प्रत्येक पृष्ठ लोड पर .htaccess को फिर से लिखना नहीं चाहते हैं।
ऐसा लगता है कि मैं अपने स्वयं के पदों को संपादित करना बंद नहीं कर सकता ... इसे शायद आपको कॉलबैक सक्रिय करना चाहिए और इसके बजाय वैश्विक $ wp_rewrite का संदर्भ देना चाहिए। और फिर non_wp_rules और आउटपुट से प्रविष्टि को .htaccess में फिर से हटाएं ताकि आप कॉलबैक को निष्क्रिय कर सकें।

और अंत में, .htaccess के लिए लेखन थोड़ा और अधिक परिष्कृत होना चाहिए, आप केवल वर्डप्रेस अनुभाग को वहां बदलना चाहते हैं।


1

मेरे पास एक समान आवश्यकता थी और अद्वितीय स्लग के आधार पर कई अंत-बिंदु बनाना चाहता था जो प्लगइन द्वारा उत्पन्न सामग्री की ओर इशारा करते थे।

मेरे प्लगइन के स्रोत पर एक नज़र है: https://wordpress.org/extend/plugins/picasa-album-nloader/

मेरे द्वारा उपयोग की जाने वाली तकनीक the_postsआने वाले अनुरोध की जांच के लिए एक फिल्टर जोड़कर शुरू होती है । यदि प्लगइन को इसे संभालना चाहिए, तो एक डमी पोस्ट उत्पन्न होता है और इसके लिए एक एक्शन जोड़ा जाता है template_redirect

जब template_redirectक्रिया को कॉल किया जाता है, तो इसका परिणाम पृष्ठ की संपूर्ण सामग्री को प्रदर्शित करने और बाहर निकलने के लिए उत्पन्न होना चाहिए या यह उत्पन्न आउटपुट के साथ वापस आ जाना चाहिए। कोड देखें wp_include/template-loader.phpऔर आप देखेंगे कि क्यों।


1

मैं एक अन्य दृष्टिकोण का उपयोग कर रहा हूं जिसमें होम पेज को कस्टम शीर्षक, सामग्री और पेज टेम्पलेट लोड करने के लिए मजबूर करना शामिल है

इसका समाधान बहुत साफ है क्योंकि इसे तब लागू किया जा सकता है जब कोई उपयोगकर्ता http://example.com/ ? Plugin_page = myfpage के अनुकूल लिंक का अनुसरण करता है ?

इसे लागू करना बहुत आसान है और असीमित पृष्ठों के लिए अनुमति देना चाहिए।

यहां कोड और निर्देश: मक्खी पर एक कस्टम / नकली / वर्चुअल वर्डप्रेस पेज बनाएं


0

मैं Xavi एस्टेव के उपरोक्त के समान एक दृष्टिकोण का उपयोग कर रहा हूं, जिसने एक वर्डप्रेस अपग्रेड के कारण काम करना बंद कर दिया है जहां तक ​​मैं 2013 की दूसरी छमाही में बता सकता हूं।

यह यहाँ पर विस्तार से प्रलेखित है: https://stackoverflow.com/questions/17960649/wordpress-plugin-generating-virtual-pages-and-using-theme-template

मेरे दृष्टिकोण का मुख्य हिस्सा मौजूदा टेम्पलेट का उपयोग कर रहा है, इसलिए परिणामी पृष्ठ ऐसा लगता है कि यह साइट का हिस्सा है; मैं चाहता था कि यह सभी विषयों के साथ संभव हो सके, उम्मीद है कि वर्डप्रेस रिलीज भर में। समय बताएगा कि क्या मैं सही था!


0

यह एक उत्पादन रीडाय उदाहरण है, पहले वर्चुअल पेज क्लास बनाएं:


class VirtualPage
{

    private $query;
    private $title;
    private $content;
    private $template;
    private $wp_post;

    function __construct($query = '/index2', $template = 'page', $title = 'Untitled')
    {
        $this->query = filter_var($query, FILTER_SANITIZE_URL);
        $this->setTemplate($template);
        $this->setTitle($title);
    }

    function getQuery()
    {
        return $this->query;
    }

    function getTemplate()
    {
        return $this->template;
    }

    function getTitle()
    {
        return $this->title;
    }

    function setTitle($title)
    {
        $this->title = filter_var($title, FILTER_SANITIZE_STRING);

        return $this;
    }

    function setContent($content)
    {
        $this->content = $content;

        return $this;
    }

    function setTemplate($template)
    {
        $this->template = $template;

        return $this;
    }

    public function updateWpQuery()
    {

        global $wp, $wp_query;

        // Update the main query
        $wp_query->current_post = $this->wp_post->ID;
        $wp_query->found_posts = 1;
        $wp_query->is_page = true;//important part
        $wp_query->is_singular = true;//important part
        $wp_query->is_single = false;
        $wp_query->is_attachment = false;
        $wp_query->is_archive = false;
        $wp_query->is_category = false;
        $wp_query->is_tag = false;
        $wp_query->is_tax = false;
        $wp_query->is_author = false;
        $wp_query->is_date = false;
        $wp_query->is_year = false;
        $wp_query->is_month = false;
        $wp_query->is_day = false;
        $wp_query->is_time = false;
        $wp_query->is_search = false;
        $wp_query->is_feed = false;
        $wp_query->is_comment_feed = false;
        $wp_query->is_trackback = false;
        $wp_query->is_home = false;
        $wp_query->is_embed = false;
        $wp_query->is_404 = false;
        $wp_query->is_paged = false;
        $wp_query->is_admin = false;
        $wp_query->is_preview = false;
        $wp_query->is_robots = false;
        $wp_query->is_posts_page = false;
        $wp_query->is_post_type_archive = false;
        $wp_query->max_num_pages = 1;
        $wp_query->post = $this->wp_post;
        $wp_query->posts = array($this->wp_post);
        $wp_query->post_count = 1;
        $wp_query->queried_object = $this->wp_post;
        $wp_query->queried_object_id = $this->wp_post->ID;
        $wp_query->query_vars['error'] = '';
        unset($wp_query->query['error']);

        $GLOBALS['wp_query'] = $wp_query;

        $wp->query = array();
        $wp->register_globals();

    }

    public function createPage()
    {
        if (is_null($this->wp_post)) {
            $post = new stdClass();
            $post->ID = -99;
            $post->ancestors = array(); // 3.6
            $post->comment_status = 'closed';
            $post->comment_count = 0;
            $post->filter = 'raw';
            $post->guid = home_url($this->query);
            $post->is_virtual = true;
            $post->menu_order = 0;
            $post->pinged = '';
            $post->ping_status = 'closed';
            $post->post_title = $this->title;
            $post->post_name = sanitize_title($this->template); // append random number to avoid clash
            $post->post_content = $this->content ?: '';
            $post->post_excerpt = '';
            $post->post_parent = 0;
            $post->post_type = 'page';
            $post->post_status = 'publish';
            $post->post_date = current_time('mysql');
            $post->post_date_gmt = current_time('mysql', 1);
            $post->modified = $post->post_date;
            $post->modified_gmt = $post->post_date_gmt;
            $post->post_password = '';
            $post->post_content_filtered = '';
            $post->post_author = is_user_logged_in() ? get_current_user_id() : 0;
            $post->post_content = '';
            $post->post_mime_type = '';
            $post->to_ping = '';

            $this->wp_post = new WP_Post($post);
            $this->updateWpQuery();

            @status_header(200);
            wp_cache_add(-99, $this->wp_post, 'posts');

        }


        return $this->wp_post;
    }
}

अगले चरण हुक template_redirectक्रिया में और नीचे की तरह अपने आभासी पृष्ठ को संभालें

    add_action( 'template_redirect', function () {


                    switch ( get_query_var( 'name' ,'') ) {

                        case 'contact':
                            // http://yoursite/contact  ==> loads page-contact.php
                            $page = new VirtualPage( "/contact", 'contact',__('Contact Me') );
                            $page->createPage();
                            break;

                        case 'archive':
                            // http://yoursite/archive  ==> loads page-archive.php
                            $page = new VirtualPage( "/archive", 'archive' ,__('Archives'));
                            $page->createPage();
                            break;

                        case 'blog':
                            // http://yoursite/blog  ==> loads page-blog.php
                            $page = new VirtualPage( "/blog", 'blog' ,__('Blog'));
                            $page->createPage();
                            break;


                }


            } );
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.