सामग्री प्रकार प्रति प्रीप्रोसेस फ़ंक्शन


25

मेरे पास कुछ सामग्री प्रकार हैं, जिन्हें मुझे अलग-अलग तरीकों से प्रीप्रोसेस करने की आवश्यकता है। इसलिए template.phpमेरे विषय में fooवर्तमान में ऐसा दिखता है:

function foo_preprocess_node(&$variables) {
    if ('news' ==$variables['type']) _preprocess_news($variables);
    if ('event'==$variables['type']) _preprocess_event($variables);
    if ('alert'==$variables['type']) _preprocess_alert($variables);
    ...
}

function _preprocess_news(&$variables) {
    ...
}

function _preprocess_event(&$variables) {
    ...
}

function _preprocess_alert(&$variables) {
    ...
}

मैं एक Drupal विशिष्ट प्रीप्रोसेस फ़ंक्शन निर्दिष्ट करने में सक्षम होना चाहता हूं जो सामग्री प्रकार के मशीन नाम पर हुक करेगा। मैंने प्रयोग करने की कोशिश की, foo_preprocess_newsलेकिन इसे कभी नहीं बुलाया गया।

क्या कोई बेहतर तरीका है?

जवाबों:


10

प्रीप्रोसेस फ़ंक्शन का नाम थीम नाम पर आधारित है, इसलिए theme_table()आपके प्रीप्रोसेस फ़ंक्शन के लिए है MYTHEME_preprocess_table()

चूंकि कोई है theme_node_node_typeसमारोह एक preprocess हुक जैसे foo_preprocess_newsया foo_preprocess_node_newsबॉक्स से बाहर काम नहीं करेगा।

आप विषय रजिस्ट्री को ओवरराइड करने के बारे में जा सकते हैं ताकि यह नोड्स के लिए अलग तरह से व्यवहार करे, लेकिन मैं वास्तव में इसकी सिफारिश नहीं करूंगा; यह बहुत गड़बड़ हो सकता है।

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

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

हालाँकि यह आपकी स्थिति के लिए ओवरकिल हो सकता है; यदि आपके पास प्रत्येक सामग्री प्रकार पर प्रदर्शन करने के लिए अतिरिक्त तर्क (यानी नॉन थीम प्रीप्रोसेस लॉजिक) नहीं है, तो यह विधि संभवतः कोई अतिरिक्त मूल्य नहीं जोड़ती है।


1
ठीक है। मैं भी foo_preprocess_nodeइसे लागू करने के रूप call_user_func('_preprocess_' . $vars['type'], $vars);में "स्वचालित" कर सकता था ताकि अगर दोहराव से बचा जा सके लेकिन यह सरल रहने के लिए सबसे अच्छा है।
चेरोविम

मैंने hook_preprocess_node()एक कस्टम मॉड्यूल पर लागू किया, और उम्मीद कर रहा था कि हुक को कॉल करने पर प्रतिबंधित होगा, लेकिन ऐसा नहीं है। जब हुक को सामग्री प्रकार द्वारा बुलाया जाता है, तो प्रतिबंधित करने का कोई तरीका?
कीवन

@Keven आप इसे लागू किया जा रहा समारोह मौजूद नहीं रोक सकता है, लेकिन if ($vars['node']->type == 'foo') { ...प्रभाव आप देख रहे हैं प्राप्त होगा
क्लाइव

मैं वास्तव में बस थोड़े से अनुकूलन की तलाश कर रहा हूं, आप के साथ क्या कर सकते हैं hook_block_view_MODULE_DELTA_alter()। मैं वर्तमान में वही करता हूं जो आप कहते हैं, लेकिन इच्छा है कि हुक हिट होने पर प्रतिबंधित करने का एक तरीका था।
Keven

यह एक अनुकूलन नहीं होगा, हालांकि @Keven - आप निर्णय लेने की प्रक्रिया को कोड के किसी अन्य भाग में स्थानांतरित कर देंगे। वास्तव में अगर द्रुपाल ने इस तरह की ओवरराइड की पेशकश की, तो इसे सामान्य होने की आवश्यकता होगी, और इसे पूरा करने के लिए लगभग निश्चित रूप से अधिक प्रोसेसर समय लगेगा। आप पहले से ही केवल आखिरी समय पर निर्णय लेने से जीत रहे हैं
क्लाइव

28

ज़ेन सबथेमे इसे अपने theme_preprocess_node फ़ंक्शन में जोड़कर पूरा करता है:

function foo_preprocess_node(&$variables, $hook) {
  ...
    // Optionally, run node-type-specific preprocess functions, like
  // foo_preprocess_node_page() or foo_preprocess_node_story().
  $function = __FUNCTION__ . '_' . $variables['node']->type;
  if (function_exists($function)) {
    $function($variables, $hook);
  } 
  ...
}

यदि आपके पास 'समाचार' नामक एक सामग्री प्रकार है, तो आप अपने टेम्पलेट.php फ़ाइल में foo_preprocess_node_news नामक एक फ़ंक्शन बनाने में सक्षम होंगे।


हम ZURB फाउंडेशन पर अपने स्वयं के इंप्लीमेंटेशन, बहुत उपयोगी कोड स्निपेट के साथ भी इसका उपयोग करते हैं।
मार्को ब्लाजाकोविक

2

मेरे पास केवल एक समान मुद्दा था जिसके कारण Google ने मुझे इस पृष्ठ पर लाया: मेरा नोड प्रीप्रोसेस फ़ंक्शन इतना बड़ा हो रहा था, कि मैं फ़ंक्शन को कई फ़ाइलों में विभाजित कर दूंगा।

मैंने पहले ही अपने template.php फ़ाइल में एक समान दृष्टिकोण किया है जिसमें सभी परिवर्तन कार्य शामिल हैं, और चूंकि एक ही विधि पूरी तरह से यहां अच्छी तरह से काम करती है, मैंने सोचा कि मैं अपना दृष्टिकोण साझा करूंगा:

फ़ोल्डर के अंदर फ़ाइल सेटअपMYTHEME/preprocess :

- node.preprocess.inc
- node--blog-post.preprocess.inc
- node--device-variation.preprocess.inc
- (...)

आपके पास पहले से ही होना चाहिए node.preprocess.inc, दूसरे आप खुद बना सकते हैं। आप उन्हें वास्तव में कैसे मनमानी कहते हैं, लेकिन बेहतर है कि उन्हें ऐसे नाम दें जो उन्हें अच्छी तरह से पहचानें और पूरे ड्रूपल नामकरण प्रणाली को फिट करें।
इन फ़ाइलों की सामग्री के लिए आगे!

node.preprocess.inc, यहाँ मैं कुछ इस तरह कर रहा हूँ:

<?php

function MYTHEME_preprocess_node(&$variables) {

    switch($variables['type']) {

      case 'blog_post':
        // if the type of the node is a Blog Post, include this:
        include 'node--blog-post.preprocess.inc';
        break;

      case 'device_variation':
        // if Device Variation, include this:
        include 'node--device-variation.preprocess.inc';
        break;

      case 'foo':
        // ...
        break;
    }

    // additional stuff for all nodes

}

हम मूल रूप से वर्तमान नोड के प्रकार के माध्यम से स्विच करते हैं। आप के माध्यम से स्विच क्या आप पर निर्भर है; #id, #view_modeसभी अपनी सटीक आवश्यकताओं पर निर्भर करता है।
एक बार मैच होने के बाद, यह निर्दिष्ट फ़ाइल को लोड करेगा और इसकी सामग्री पर कार्य करेगा जैसे कि यह इस फ़ंक्शन के अंदर लिखा गया हो।

इन includedफ़ाइलों की सामग्री ठीक वैसी ही लगती है, जैसे आप इसे node.preprocess.incफ़ाइल में रखते हैं, सिवाय इसके कि हम प्रीप्रोसेस फ़ंक्शन को फिर से कॉल न करें:

node--device-variation.preprocess.inc

<?php

    // Device Name
    $device = drupal_clean_css_identifier(strtolower($variables['title']));

    // Determine whether only Device Version is of type 'N/A' and set ppvHasVariations accordingly
    $deviceHasVariations = true;
    if( $variables['content']['product:field_model_variation'][0]['#options']['entity']->weight == 0 ) {
        $deviceHasVariations = false;
    }
    //...

आप मूल रूप से कई फ़ाइलों के साथ ऐसा कर सकते हैं, जैसा कि आप चाहते हैं और यहां तक ​​कि कई स्विचों को कैस्केड कर सकते हैं, उदाहरण के लिए, विशिष्ट नोड प्रीप्रोसेस फ़ाइलों के आधार पर आगे विभाजन करना #view_mode, fullव्यू मोड के लिए एक फ़ाइल और दूसरे के लिए दूसरा होना।teaser

उम्मीद है कि यह मदद करता है, किसी को कभी इस सवाल पर ठोकर चाहिए (:


1

call_user_func()संदर्भ द्वारा पैरामीटर पारित नहीं करता है। तो, $variablesअपने preprocess_foo()कार्यों के मामले में केवल मूल सरणी की प्रतियों पर काम करेगा; शेष रेंडर प्रक्रिया के दौरान गैर-ऑब्जेक्ट पर परिवर्तन लागू नहीं होंगे।


1

अपने मुख्य hook_preprocess_node में अंत में निम्नलिखित कोड लागू करें

$preprocess_function = 'themename_node__' . $node->type . '__preprocess';
if (function_exists($preprocess_function)) {
 $preprocess_function($variables);
}

तो आप अब नोड प्रकार से प्रीप्रोसेस करेंगे

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