আপনি যখন কোনও ফ্রন্টএন্ড পৃষ্ঠাতে যান, তখন ওয়ার্ডপ্রেস ডাটাবেসটিকে জিজ্ঞাসা করবে এবং যদি আপনার পৃষ্ঠাটি ডাটাবেসে উপস্থিত না থাকে, তবে সেই ক্যোয়ারির প্রয়োজন হয় না এবং এটি কেবল সম্পদের অপচয়।
ভাগ্যক্রমে, ওয়ার্ডপ্রেস একটি কাস্টম উপায়ে সম্মুখভাগ অনুরোধগুলি পরিচালনা করার জন্য একটি উপায় সরবরাহ করে। যে 'do_parse_request'
ফিল্টার ধন্যবাদ করা হয় ।
এই হুকটিতে ফিরে এসে false
আপনি ওয়ার্ডপ্রেসকে অনুরোধগুলি প্রক্রিয়া করা থেকে বিরত করতে এবং এটি নিজের কাস্টম পদ্ধতিতে করতে সক্ষম হবেন।
এটি বলেছিল, আমি একটি সাধারণ ওওপি প্লাগইন তৈরির এমন একটি উপায় ভাগ করতে চাই যা ভার্চুয়াল পৃষ্ঠাগুলিকে সহজেই ব্যবহারযোগ্য (এবং পুনরায় ব্যবহার) উপায়ে পরিচালনা করতে পারে।
আমাদের কি দরকার
- ভার্চুয়াল পৃষ্ঠা অবজেক্টের জন্য একটি শ্রেণি
- একটি নিয়ামক শ্রেণি, এটি একটি অনুরোধ দেখবে এবং যদি এটি ভার্চুয়াল পৃষ্ঠার জন্য হয় তবে সঠিক টেম্পলেট ব্যবহার করে এটি দেখান
- টেমপ্লেট লোড করার জন্য একটি শ্রেণি
- হুকগুলি যুক্ত করতে প্রধান প্লাগইন ফাইলগুলি যা সবকিছুকে কাজ করবে
ইন্টারফেস
ক্লাস তৈরির আগে, উপরের তালিকাভুক্ত 3 টি অবজেক্টের জন্য ইন্টারফেস লিখি।
প্রথম পৃষ্ঠা ইন্টারফেস (ফাইল PageInterface.php
):
<?php
namespace GM\VirtualPages;
interface PageInterface {
function getUrl();
function getTemplate();
function getTitle();
function setTitle( $title );
function setContent( $content );
function setTemplate( $template );
/**
* Get a WP_Post build using virtual Page object
*
* @return \WP_Post
*/
function asWpPost();
}
বেশিরভাগ পদ্ধতিগুলি কেবল গেটার এবং সেটটার, ব্যাখ্যা দেওয়ার দরকার নেই। WP_Post
ভার্চুয়াল পৃষ্ঠা থেকে কোনও অবজেক্ট পেতে সর্বশেষ পদ্ধতিটি ব্যবহার করা উচিত ।
নিয়ামক ইন্টারফেস (ফাইল ControllerInterface.php
):
<?php
namespace GM\VirtualPages;
interface ControllerInterface {
/**
* Init the controller, fires the hook that allows consumer to add pages
*/
function init();
/**
* Register a page object in the controller
*
* @param \GM\VirtualPages\Page $page
* @return \GM\VirtualPages\Page
*/
function addPage( PageInterface $page );
/**
* Run on 'do_parse_request' and if the request is for one of the registered pages
* setup global variables, fire core hooks, requires page template and exit.
*
* @param boolean $bool The boolean flag value passed by 'do_parse_request'
* @param \WP $wp The global wp object passed by 'do_parse_request'
*/
function dispatch( $bool, \WP $wp );
}
এবং টেমপ্লেট লোডার ইন্টারফেস (ফাইল TemplateLoaderInterface.php
):
<?php
namespace GM\VirtualPages;
interface TemplateLoaderInterface {
/**
* Setup loader for a page objects
*
* @param \GM\VirtualPagesPageInterface $page matched virtual page
*/
public function init( PageInterface $page );
/**
* Trigger core and custom hooks to filter templates,
* then load the found template.
*/
public function load();
}
এই ইন্টারফেসের জন্য পিএইচপিডোকের মন্তব্যগুলি বেশ পরিষ্কার হওয়া উচিত।
পরিকল্পনা
এখন আমাদের ইন্টারফেস রয়েছে এবং কংক্রিটের ক্লাস লেখার আগে আসুন আমাদের কর্মপ্রবাহটি পর্যালোচনা করুন:
- প্রথমে আমরা একটি
Controller
ক্লাস ইনস্ট্যান্ট করি (বাস্তবায়নকারী ControllerInterface
) এবং ইনজেকশন (সম্ভবত কোনও নির্মাণকারী) TemplateLoader
ক্লাসের একটি উদাহরণ (প্রয়োগকারী TemplateLoaderInterface
)
- উপর
init
হুক আমরা কল ControllerInterface::init()
সেটআপ পদ্ধতি কন্ট্রোলার এবং হুক যা ভোক্তা কোড ভার্চুয়াল পৃষ্ঠাগুলি যোগ করার জন্য ব্যবহার করা হবে আগুনে।
- উপর 'do_parse_request' আমরা ডাকব
ControllerInterface::dispatch()
, এবং আমরা সবাই ভার্চুয়াল পৃষ্ঠাগুলি যোগ চেক করবে এবং যদি তাদের মধ্যে একজন বর্তমান অনুরোধের একই URL আছে, এটা প্রদর্শন; সমস্ত মূল বৈশ্বিক চলক ( $wp_query
, $post
) সেট করার পরে । আমরা TemplateLoader
সঠিক টেমপ্লেট লোড করতে শ্রেণিও ব্যবহার করব ।
এই ওয়ার্কফ্লোটি আমরা কিছু কোর আঙ্গুলসমূহ আরম্ভ হবে সময়, মত wp
, template_redirect
, template_include
... প্লাগইন নমনীয় করতে এবং কোর এবং অন্যান্য প্লাগিন, অথবা তাদের একটি ভাল নম্বর দিয়ে অন্তত সাথে সামঞ্জস্যের নিশ্চিত করতে হবে।
পূর্ববর্তী ওয়ার্কফ্লো বাদে আমাদেরও এগুলি করতে হবে:
- মূল এবং তৃতীয় পক্ষের কোডের সাথে সামঞ্জস্যতা উন্নত করতে আবার প্রধান লুপ রান হওয়ার পরে হুক এবং গ্লোবাল ভেরিয়েবলগুলি পরিষ্কার করুন
the_permalink
যখন প্রয়োজন হয় তখন ডান ভার্চুয়াল পৃষ্ঠা URL ফিরিয়ে আনতে একটি ফিল্টার যুক্ত করুন ।
কংক্রিট ক্লাস
এখন আমরা আমাদের কংক্রিট ক্লাস কোড করতে পারি। আসুন পৃষ্ঠার শ্রেণি (ফাইল Page.php
) দিয়ে শুরু করুন :
<?php
namespace GM\VirtualPages;
class Page implements PageInterface {
private $url;
private $title;
private $content;
private $template;
private $wp_post;
function __construct( $url, $title = 'Untitled', $template = 'page.php' ) {
$this->url = filter_var( $url, FILTER_SANITIZE_URL );
$this->setTitle( $title );
$this->setTemplate( $template);
}
function getUrl() {
return $this->url;
}
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;
}
function asWpPost() {
if ( is_null( $this->wp_post ) ) {
$post = array(
'ID' => 0,
'post_title' => $this->title,
'post_name' => sanitize_title( $this->title ),
'post_content' => $this->content ? : '',
'post_excerpt' => '',
'post_parent' => 0,
'menu_order' => 0,
'post_type' => 'page',
'post_status' => 'publish',
'comment_status' => 'closed',
'ping_status' => 'closed',
'comment_count' => 0,
'post_password' => '',
'to_ping' => '',
'pinged' => '',
'guid' => home_url( $this->getUrl() ),
'post_date' => current_time( 'mysql' ),
'post_date_gmt' => current_time( 'mysql', 1 ),
'post_author' => is_user_logged_in() ? get_current_user_id() : 0,
'is_virtual' => TRUE,
'filter' => 'raw'
);
$this->wp_post = new \WP_Post( (object) $post );
}
return $this->wp_post;
}
}
ইন্টারফেস বাস্তবায়ন ছাড়া আর কিছুই নয়।
এখন নিয়ামক শ্রেণি (ফাইল Controller.php
):
<?php
namespace GM\VirtualPages;
class Controller implements ControllerInterface {
private $pages;
private $loader;
private $matched;
function __construct( TemplateLoaderInterface $loader ) {
$this->pages = new \SplObjectStorage;
$this->loader = $loader;
}
function init() {
do_action( 'gm_virtual_pages', $this );
}
function addPage( PageInterface $page ) {
$this->pages->attach( $page );
return $page;
}
function dispatch( $bool, \WP $wp ) {
if ( $this->checkRequest() && $this->matched instanceof Page ) {
$this->loader->init( $this->matched );
$wp->virtual_page = $this->matched;
do_action( 'parse_request', $wp );
$this->setupQuery();
do_action( 'wp', $wp );
$this->loader->load();
$this->handleExit();
}
return $bool;
}
private function checkRequest() {
$this->pages->rewind();
$path = trim( $this->getPathInfo(), '/' );
while( $this->pages->valid() ) {
if ( trim( $this->pages->current()->getUrl(), '/' ) === $path ) {
$this->matched = $this->pages->current();
return TRUE;
}
$this->pages->next();
}
}
private function getPathInfo() {
$home_path = parse_url( home_url(), PHP_URL_PATH );
return preg_replace( "#^/?{$home_path}/#", '/', esc_url( add_query_arg(array()) ) );
}
private function setupQuery() {
global $wp_query;
$wp_query->init();
$wp_query->is_page = TRUE;
$wp_query->is_singular = TRUE;
$wp_query->is_home = FALSE;
$wp_query->found_posts = 1;
$wp_query->post_count = 1;
$wp_query->max_num_pages = 1;
$posts = (array) apply_filters(
'the_posts', array( $this->matched->asWpPost() ), $wp_query
);
$post = $posts[0];
$wp_query->posts = $posts;
$wp_query->post = $post;
$wp_query->queried_object = $post;
$GLOBALS['post'] = $post;
$wp_query->virtual_page = $post instanceof \WP_Post && isset( $post->is_virtual )
? $this->matched
: NULL;
}
public function handleExit() {
exit();
}
}
মূলত শ্রেণি একটি SplObjectStorage
অবজেক্ট তৈরি করে যেখানে সমস্ত যুক্ত পৃষ্ঠাগুলি অবজেক্টগুলি সংরক্ষণ করা হয়।
চালু 'do_parse_request'
, যোগ করা পৃষ্ঠাগুলির মধ্যে একটিতে বর্তমান URL টির মিল খুঁজে পেতে নিয়ন্ত্রণকারী শ্রেণি এই স্টোরেজটি লুপ করে।
যদি এটি পাওয়া যায়, ক্লাসটি ঠিক তেমনভাবে পরিকল্পনা করেছিল যা আমরা পরিকল্পনা করেছি: কিছু হুক, সেটআপ ভেরিয়েবলগুলি ট্রিগার করুন এবং শ্রেণিবদ্ধকরণের মাধ্যমে টেমপ্লেট লোড করুন TemplateLoaderInterface
। তার পরে, ঠিক exit()
।
সুতরাং আসুন শেষ ক্লাস লিখুন:
<?php
namespace GM\VirtualPages;
class TemplateLoader implements TemplateLoaderInterface {
public function init( PageInterface $page ) {
$this->templates = wp_parse_args(
array( 'page.php', 'index.php' ), (array) $page->getTemplate()
);
}
public function load() {
do_action( 'template_redirect' );
$template = locate_template( array_filter( $this->templates ) );
$filtered = apply_filters( 'template_include',
apply_filters( 'virtual_page_template', $template )
);
if ( empty( $filtered ) || file_exists( $filtered ) ) {
$template = $filtered;
}
if ( ! empty( $template ) && file_exists( $template ) ) {
require_once $template;
}
}
}
ভার্চুয়াল পৃষ্ঠা সঞ্চিত টেমপ্লেট অক্ষমতা সঙ্গে একটি অ্যারের মধ্যে মিশে গিয়ে তৈরি হয় page.php
এবং index.php
, আগে লোডিং টেমপ্লেট 'template_redirect'
বহিস্কার করা হয়, নমনীয়তা যোগ করতে পারেন এবং সামঞ্জস্য উন্নত।
এর পরে, প্রাপ্ত টেমপ্লেটটি কাস্টম 'virtual_page_template'
এবং মূল 'template_include'
ফিল্টারগুলির মধ্য দিয়ে যায় : আবার নমনীয়তা এবং সামঞ্জস্যের জন্য।
অবশেষে টেমপ্লেট ফাইলটি সবেমাত্র লোড হয়েছে।
প্রধান প্লাগইন ফাইল
এই মুহুর্তে আমাদের প্লাগইন শিরোনাম সহ ফাইলটি লিখতে হবে এবং হুকগুলি যুক্ত করতে এটি ব্যবহার করতে হবে যা আমাদের কর্মপ্রবাহকে ঘটায়:
<?php namespace GM\VirtualPages;
/*
Plugin Name: GM Virtual Pages
*/
require_once 'PageInterface.php';
require_once 'ControllerInterface.php';
require_once 'TemplateLoaderInterface.php';
require_once 'Page.php';
require_once 'Controller.php';
require_once 'TemplateLoader.php';
$controller = new Controller ( new TemplateLoader );
add_action( 'init', array( $controller, 'init' ) );
add_filter( 'do_parse_request', array( $controller, 'dispatch' ), PHP_INT_MAX, 2 );
add_action( 'loop_end', function( \WP_Query $query ) {
if ( isset( $query->virtual_page ) && ! empty( $query->virtual_page ) ) {
$query->virtual_page = NULL;
}
} );
add_filter( 'the_permalink', function( $plink ) {
global $post, $wp_query;
if (
$wp_query->is_page && isset( $wp_query->virtual_page )
&& $wp_query->virtual_page instanceof Page
&& isset( $post->is_virtual ) && $post->is_virtual
) {
$plink = home_url( $wp_query->virtual_page->getUrl() );
}
return $plink;
} );
আসল ফাইলে আমরা সম্ভবত আরও শিরোনাম যুক্ত করব, যেমন প্লাগইন এবং লেখকের লিঙ্ক, বিবরণ, লাইসেন্স ইত্যাদি add
প্লাগিন গিস্ট
ঠিক আছে, আমরা আমাদের প্লাগইন দিয়ে কাজ শেষ করেছি। সমস্ত কোড এখানে একটি সংক্ষেপে পাওয়া যাবে ।
পৃষ্ঠা যুক্ত করা হচ্ছে
প্লাগইন প্রস্তুত এবং কাজ করছে, তবে আমরা কোনও পৃষ্ঠা যুক্ত করি নি।
এটি প্লাগইনের ভিতরেই, থিমের অভ্যন্তরে functions.php
, অন্য একটি প্লাগইনে করা যেতে পারে etc.
পৃষ্ঠা যুক্ত করা কেবল একটি বিষয়:
<?php
add_action( 'gm_virtual_pages', function( $controller ) {
// first page
$controller->addPage( new \GM\VirtualPages\Page( '/custom/page' ) )
->setTitle( 'My First Custom Page' )
->setTemplate( 'custom-page-form.php' );
// second page
$controller->addPage( new \GM\VirtualPages\Page( '/custom/page/deep' ) )
->setTitle( 'My Second Custom Page' )
->setTemplate( 'custom-page-deep.php' );
} );
ইত্যাদি। আপনার প্রয়োজনীয় সমস্ত পৃষ্ঠাগুলি যোগ করতে পারেন, কেবল পৃষ্ঠাগুলির জন্য আপেক্ষিক ইউআরএল ব্যবহার করতে ভুলবেন না।
টেম্পলেট ফাইলের অভ্যন্তরে আপনি সমস্ত ওয়ার্ডপ্রেস টেম্পলেট ট্যাগ ব্যবহার করতে পারেন এবং আপনার প্রয়োজনীয় সমস্ত পিএইচপি এবং এইচটিএমএল লিখতে পারেন।
গ্লোবাল পোস্ট অবজেক্টটি আমাদের ভার্চুয়াল পৃষ্ঠা থেকে আসা ডেটাতে পূর্ণ। ভার্চুয়াল পৃষ্ঠাটি নিজেই $wp_query->virtual_page
ভেরিয়েবলের মাধ্যমে অ্যাক্সেস করা যায় ।
ভার্চুয়াল পৃষ্ঠার জন্য ইউআরএল পাওয়া পৃষ্ঠাটি home_url()
তৈরি করতে ব্যবহৃত একই পাথের পাশ দিয়ে যাওয়ার মতোই সহজ :
$custom_page_url = home_url( '/custom/page' );
নোট করুন যে লোড হওয়া টেমপ্লেটের মূল লুপটিতে the_permalink()
ভার্চুয়াল পৃষ্ঠায় সঠিক পারমিলিংক ফিরে আসবে।
ভার্চুয়াল পৃষ্ঠাগুলির জন্য স্টাইল / স্ক্রিপ্টগুলির নোট
সম্ভবত যখন ভার্চুয়াল পৃষ্ঠাগুলি যুক্ত করা হয় তখন কাস্টম শৈলী / স্ক্রিপ্টগুলি সজ্জিত করা এবং তারপরে কেবল wp_head()
কাস্টম টেম্পলেটগুলিতে ব্যবহার করা বাঞ্ছনীয় ।
এটি খুব সহজ, কারণ ভার্চুয়াল পৃষ্ঠাগুলি সহজেই $wp_query->virtual_page
ভেরিয়েবলের দিকে তাকানো স্বীকৃত হয় এবং ভার্চুয়াল পৃষ্ঠাগুলি তাদের ইউআরএলগুলি দেখে অন্যের থেকে আলাদা করা যায়।
শুধু একটি উদাহরণ:
add_action( 'wp_enqueue_scripts', function() {
global $wp_query;
if (
is_page()
&& isset( $wp_query->virtual_page )
&& $wp_query->virtual_page instanceof \GM\VirtualPages\PageInterface
) {
$url = $wp_query->virtual_page->getUrl();
switch ( $url ) {
case '/custom/page' :
wp_enqueue_script( 'a_script', $a_script_url );
wp_enqueue_style( 'a_style', $a_style_url );
break;
case '/custom/page/deep' :
wp_enqueue_script( 'another_script', $another_script_url );
wp_enqueue_style( 'another_style', $another_style_url );
break;
}
}
} );
ওপিকে নোটস
কোনও পৃষ্ঠা থেকে অন্য পৃষ্ঠায় ডেটা পাঠানো এই ভার্চুয়াল পৃষ্ঠাগুলির সাথে সম্পর্কিত নয়, তবে এটি কেবল একটি জেনেরিক কাজ।
তবে, যদি প্রথম পৃষ্ঠায় আপনার একটি ফর্ম থাকে এবং সেখান থেকে দ্বিতীয় পৃষ্ঠায় ডেটা পাস করতে চান তবে কেবলমাত্র ফর্ম action
সম্পত্তিতে দ্বিতীয় পৃষ্ঠার ইউআরএল ব্যবহার করুন ।
যেমন প্রথম পৃষ্ঠার টেম্পলেট ফাইলটিতে আপনি করতে পারেন:
<form action="<?php echo home_url( '/custom/page/deep' ); ?>" method="POST">
<input type="text" name="testme">
</form>
এবং তারপরে দ্বিতীয় পৃষ্ঠার টেম্পলেট ফাইলটিতে:
<?php $testme = filter_input( INPUT_POST, 'testme', FILTER_SANITIZE_STRING ); ?>
<h1>Test-Me value form other page is: <?php echo $testme; ?></h1>