एक प्लगइन में एक कस्टम पोस्ट प्रकार के लिए एक कस्टम संग्रह पृष्ठ बनाएँ


11

मैं एक प्लगइन लिख रहा हूँ, जो "my_plugin_lesson" नामक एक कस्टम पोस्ट प्रकार बनाता है:

$args = array (
    'public' => true,
    'has_archive' => true,
    'rewrite' => array('slug' => 'lessons', 'with_front' => false)
);
register_post_type ('my_plugin_lesson', $args);

कस्टम पोस्ट प्रकार में एक संग्रह है, और संग्रह का URL है:

http://example.com/lessons

मैं इस संग्रह के रूप को अनुकूलित करना चाहता हूं; मैं मानक वर्डप्रेस ब्लॉग पोस्ट संग्रह के बजाय तालिका प्रारूप में पदों को सूचीबद्ध करना चाहता हूं। मैं समझता हूं कि archive-my_plugin_lesson.phpफ़ाइल बनाकर थीम में एक कस्टम संग्रह टेम्पलेट बनाया जा सकता है ; हालाँकि, मैं किसी भी विषय के साथ काम करना चाहता हूँ।

मैं थीम फ़ाइलों को जोड़ने या संशोधित किए बिना संग्रह पृष्ठ की सामग्री को कैसे बदल सकता हूं?

संपादित करें: मैं समझता हूं कि मैं archive_templateफिल्टर हुक का उपयोग कर सकता हूं । हालाँकि, यह सब विषय टेम्पलेट को प्रतिस्थापित करता है, जिसे अभी भी विषय-विशेष की आवश्यकता है। उदाहरण के लिए, लगभग हर विषय टेम्पलेट की आवश्यकता होगी get_header, get_sidebarऔर get_footerकाम करता है, लेकिन क्या सामग्री की आईडी चाहिए <div>हो सकता है? यह हर थीम में अलग है।

मैं क्या करना चाहूंगा कि सामग्री को स्वयं अपनी सामग्री से प्रतिस्थापित करना है, और मेरे कस्टम पोस्ट प्रकार के लिए संग्रह पृष्ठ के स्थान पर इसका उपयोग करना है।

जवाबों:


12

आपको जिस चीज़ की ज़रूरत होती है वह है हुकिंग template_includeफ़िल्टर और चुनिंदा रूप से अपने टेम्पलेट को प्लगइन के अंदर लोड करना।

एक अच्छा अभ्यास के रूप में, यदि आप अपने प्लगइन को वितरित करने की योजना बनाते हैं, तो आपको यह जांचना चाहिए कि क्या archive-my_plugin_lesson.php(या शायद myplugin/archive-lesson.php) थीम में मौजूद है, यदि प्लगइन संस्करण का उपयोग नहीं किया गया है।

इस तरह से उपयोगकर्ताओं को प्लगइन कोड को संपादित किए बिना थीम (या चाइल्ड थीम) के माध्यम से टेम्पलेट को बदलना आसान है।

यह लोकप्रिय प्लगइन्स द्वारा उपयोग की जाने वाली विधि है, जैसे WooCommmerce, केवल एक नाम कहने के लिए।

add_filter('template_include', 'lessons_template');

function lessons_template( $template ) {
  if ( is_post_type_archive('my_plugin_lesson') ) {
    $theme_files = array('archive-my_plugin_lesson.php', 'myplugin/archive-lesson.php');
    $exists_in_theme = locate_template($theme_files, false);
    if ( $exists_in_theme != '' ) {
      return $exists_in_theme;
    } else {
      return plugin_dir_path(__FILE__) . 'archive-lesson.php';
    }
  }
  return $template;
}

के लिए कोडेक्स पर अधिक जानकारी


यह अभी भी थीम के टेम्पलेट फ़ाइल को बदलता है, है ना? मैं अपने प्लगइन के संग्रह-lesson.php फ़ाइल में क्या डालूँ? प्रत्येक विषय के साथ काम करने के लिए अलग होना आवश्यक है। यहां तक ​​कि डिफ़ॉल्ट "ट्वेंटी" थीम इस बात पर सहमत नहीं हैं कि सामग्री को घेरने वाले div / अनुभाग कंटेनर क्या हैं।
बेन मिलर -

7

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

योजना फिल्टर $tpl_strमें टेम्पलेट को एक स्ट्रिंग ( ) में लोड करने के लिए है archive_template, अपनी सामग्री को प्रतिस्थापित करें, स्ट्रिंग को शामिल करें (ट्रिक का उपयोग करके eval( '?>' . $tpl_str );), और फिर एक खाली फ़ाइल लौटाएं ताकि include"wp- / /-loader.php" शामिल हो। एक नहीं सेशन बन जाता है।

नीचे एक प्लगइन में उपयोग किए गए कोड का हैक किया गया संस्करण है, जो "क्लासिक" टेम्प्लेट को लक्षित करता है जो कि get_template_partसंग्रह की तुलना में एकल टेम्प्लेट के प्रसंस्करण के साथ उपयोग करते हैं और अधिक चिंतित हैं, लेकिन आपको आरंभ करने में मदद करनी चाहिए। सेटअप यह है कि प्लगइन में "टेम्प्लेट" नामक एक उपनिर्देशिका है जो एक रिक्त फ़ाइल ("null.php") और सामग्री टेम्प्लेट (उदाहरण के लिए "सामग्री-एकल- posttype1.php", "सामग्री-संग्रह-पोस्ट टाइप 1। Php") रखती है। सिंगल केस के लिए "बैक. टेम्पलेट" के साथ-साथ फ़ॉल बैक टेम्पलेट, और get_template_partइस निर्देशिका में कस्टम संस्करण का उपयोग करता है ।

define( 'MYPLUGIN_FOLDER', dirname( __FILE__ ) . '/' );
define( 'MYPLUGIN_BASENAME', basename( MYPLUGIN_FOLDER ) );

add_filter( 'single_template', 'myplugin_single_template' );
add_filter( 'archive_template', 'myplugin_archive_template' );

function myplugin_single_template( $template ) {
    static $using_null = array();

    // Adjust with your custom post types.
    $post_types = array( 'posttype1', );

    if ( is_single() || is_archive() ) {
        $template_basename = basename( $template );
        // This check can be removed.
        if ( $template == '' || substr( $template_basename, 0, 4 ) == 'sing' || substr( $template_basename, 0, 4 ) == 'arch' ) {
            $post_type = get_post_type();
            $slug = is_archive() ? 'archive' : 'single';
            if ( in_array( $post_type, $post_types ) ) {
                // Allow user to override.
                if ( $single_template = myplugin_get_template( $slug, $post_type ) ) {
                    $template = $single_template;
                } else {
                    // If haven't gone through all this before...
                    if ( empty( $using_null[$slug][$post_type] ) ) {
                        if ( $template && ( $content_template = myplugin_get_template( 'content-' . $slug, $post_type ) ) ) {
                            $tpl_str = file_get_contents( $template );
                            // You'll have to adjust these regexs to your own case - good luck!
                            if ( preg_match( '/get_template_part\s*\(\s*\'content\'\s*,\s*\'' . $slug . '\'\s*\)/', $tpl_str, $matches, PREG_OFFSET_CAPTURE )
                            || preg_match( '/get_template_part\s*\(\s*\'content\'\s*,\s*get_post_format\s*\(\s*\)\s*\)/', $tpl_str, $matches, PREG_OFFSET_CAPTURE )
                            || preg_match( '/get_template_part\s*\(\s*\'content\'\s*\)/', $tpl_str, $matches, PREG_OFFSET_CAPTURE )
                            || preg_match( '/get_template_part\s*\(\s*\'[^\']+\'\s*,\s*\'' . $slug . '\'\s*\)/', $tpl_str, $matches, PREG_OFFSET_CAPTURE ) ) {
                                $using_null[$slug][$post_type] = true;
                                $tpl_str = substr( $tpl_str, 0, $matches[0][1] ) . 'include \'' . $content_template . '\'' . substr( $tpl_str, $matches[0][1] + strlen( $matches[0][0] ) );
                                // This trick includes the $tpl_str.
                                eval( '?>' . $tpl_str );
                            }
                        }
                    }
                    if ( empty( $using_null[$slug][$post_type] ) ) {
                        // Failed to parse - look for fall back template.
                        if ( file_exists( MYPLUGIN_FOLDER . 'templates/' . $slug . '.php' ) ) {
                            $template = MYPLUGIN_FOLDER . 'templates/' . $slug . '.php';
                        }
                    } else {
                        // Success! "null.php" is just a blank zero-byte file.
                        $template = MYPLUGIN_FOLDER . 'templates/null.php';
                    }
                }
            }
        }
    }
    return $template;
}

function myplugin_archive_template( $template ) {
    return myplugin_single_template( $template );
}

कस्टम get_template_part:

/*
 * Version of WP get_template_part() that looks in theme, then parent theme, and finally in plugin template directory (sub-directory "templates").
 * Also looks initially in "myplugin" sub-directory if any in theme and parent theme directories so that plugin templates can be kept separate.
 */
function myplugin_get_template( $slug, $part = '' ) {
    $template = $slug . ( $part ? '-' . $part : '' ) . '.php';

    $dirs = array();

    if ( is_child_theme() ) {
        $child_dir = get_stylesheet_directory() . '/';
        $dirs[] = $child_dir . MYPLUGIN_BASENAME . '/';
        $dirs[] = $child_dir;
    }

    $template_dir = get_template_directory() . '/';
    $dirs[] = $template_dir . MYPLUGIN_BASENAME . '/';
    $dirs[] = $template_dir;
    $dirs[] = MYPLUGIN_FOLDER . 'templates/';

    foreach ( $dirs as $dir ) {
        if ( file_exists( $dir . $template ) ) {
            return $dir . $template;
        }
    }
    return false;
}

पूर्णता के लिए यहाँ "सिंगल.फ्प" की गिरावट है, जो कस्टम का उपयोग करती है get_template_part:

<?php
get_header(); ?>

    <div id="primary" class="content-area">
        <div id="content" class="clearfix">
            <?php while ( have_posts() ) : the_post(); ?>

            <?php if ( $template = myplugin_get_template( 'content-single', get_post_type() ) ) include $template; else get_template_part( 'content', 'single' ); ?>

                <?php
                    // If comments are open or we have at least one comment, load up the comment template
                    if ( comments_open() || '0' != get_comments_number() ) :
                        comments_template();
                    endif;
                ?>

            <?php endwhile; ?>

        </div><!-- #content -->
    </div><!-- #primary -->

<?php get_sidebar(); ?>
<?php get_footer(); ?>

1

मैं एक ही प्रश्न की ओर इशारा कर रहा हूं, और यह वह काल्पनिक समाधान है जो मैं लेकर आया हूं:

  • प्लगइन के भीतर, एक शोर्ट बनाएं जो आपके संग्रह को आउटपुट करता है जिस तरह से आप चाहते हैं।
  • कस्टम पोस्ट प्रकार बनाते समय, 'संग्रह' विकल्प को सक्षम न करें।
  • एक स्टाइलशीट जोड़ें जो आपकी लूप सामग्री की सभी शैलियों को नियंत्रित करती है।

प्लगइन सक्रियण पर wp_insert_post का उपयोग करके एक पेज बनाते हैं, जिसमें नाम पोस्ट प्रकार और सामग्री शोर्ट होने के साथ होता है।

आप अतिरिक्त शैली के विचारों के लिए शोर्ट में विकल्प प्रदान कर सकते हैं, या थीम विशिष्ट या कस्टम शैलियों से मेल करने के लिए पोस्ट कंटेनर में कक्षाएं जोड़ सकते हैं। उपयोगकर्ता पृष्ठ को संपादित करके लूप से पहले / बाद में अतिरिक्त सामग्री भी जोड़ सकता है।


ओपी नहीं होने के बावजूद, मैं उसी समस्या का हल ढूंढ रहा था। मैंने आपके काल्पनिक समाधान का अनुसरण किया है और अब मैं इसकी पुष्टि कर सकता हूं कि यह व्यवहार में भी काम करता है।
लुसियो क्रुस्का

हे महान! खुशी है कि यह किसी के लिए उपयोगी था। मैं इस बारे में पूरी तरह से भूल चुका था।
SkyShab

0

आप फ़िल्टर का उपयोग कर सकते हैं single_templateकोडेक्स से लिया गया एक मूल उदाहरण :

function get_custom_post_type_template($single_template) {
     global $post;

     if ($post->post_type == 'my_post_type') {
          $single_template = dirname( __FILE__ ) . '/post-type-template.php';
     }
     return $single_template;
}

add_filter( "single_template", "get_custom_post_type_template" );

मुझे लगता है कि संग्रह टेम्पलेट के लिए फ़िल्टर हुक है archive_template, लेकिन मुझे नहीं लगता कि यह वह काम करेगा जो मैं करने की कोशिश कर रहा हूं। मैंने अपने प्रश्न को अधिक जानकारी के साथ संपादित किया है।
बेन मिलर -
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.