İçerik türü başına ön işleme işlevi


25

Farklı şekillerde ön işleme almam gereken birkaç içerik türü var. Yani template.phpbenim tema fooşu anda gibi görünüyor:

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) {
    ...
}

İçerik türünün makine adını bağlayacak bir Drupal spesifik ön işleme işlevi belirtebilmek istiyorum. Kullanmayı denedim foo_preprocess_newsama hiç aranmadı.

Daha iyi bir yolu var mı?

Yanıtlar:


10

Ön işleme işlevinin adı, tema adına dayalıdır, bu nedenle theme_table()ön işlem işleviniz için MYTHEME_preprocess_table().

theme_node_node_typeİşlev olmadığından, ön işleme kancası gibi foo_preprocess_newsveya foo_preprocess_node_newskutudan çıkamayan bir kanca .

Sen olabilir o düğümler için farklı davranış, böylece tema kayıt geçersiz kılma hakkında gitmek, ama gerçekten bunu tavsiye etmem; çok karışık olabilirdi.

Ben yeniden kodlama kodunun büyük bir hayranıyım ama senin durumunda gerekli olduğunu sanmıyorum; ön işleme kancanızda düğüm tipine bağlı olarak çalıştırılması gereken karmaşık bir mantık varsa, o zaman yaptığınız şekilde farklı işlevlere sahip olmak bana iyi bir uygulama gibi geliyor.

Elbette diğer yöntem, farklı içerik türlerinin her biri için özel bir modül uygulamak hook_preprocess_node()ve bunların her birinde uygulamak olacaktır . Bu şekilde, her modülün ön işleme işlevi farklı bir içerik türünden sorumlu olabilir.

Ancak bu durumunuz için fazla abartılmış olabilir; Her içerik türünde gerçekleştirecek fazladan bir mantık (yani tema öncesi işlem yapma mantığı) yoksa, bu yöntem muhtemelen fazladan bir değer katmaz.


1
TAMAM. Ayrıca ifleri tekrarlamaktan kaçınmak için foo_preprocess_nodeuygulayarak "otomatikleştirebilirim" call_user_func('_preprocess_' . $vars['type'], $vars);ama muhtemelen basit kalmak en iyisidir.
cherouvim

hook_preprocess_node()Özel bir modülde uygulamıştım ve kanca çağrıldığında kısıtlanacağını umuyordum, ama değil. Kanca içerik türüne göre çağrıldığında kısıtlamanın bir yolu var mı?
Keven

@Keven İşlev varsa, çağrılmasını durduramazsınız, ancak if ($vars['node']->type == 'foo') { ...aradığınız efekti elde edersiniz
Clive

Gerçekten yapabileceğin şeylere benzeyen hafif bir optimizasyon arıyorum hook_block_view_MODULE_DELTA_alter(). Şu anda söylediklerini yapıyorum, ancak kancayı vurduğunda kısıtlamanın bir yolu olsaydı.
Keven

@Keven olsa da bu bir optimizasyon olmazdı - karar verme sürecini sadece kodun başka bir bölümüne kaydırıyordunuz. Aslında, eğer Drupal böyle bir geçersiz kılma teklif ettiyse, genel olması gerekirdi ve başarmak için neredeyse kesinlikle daha fazla işlemci zamanı harcardı. Zaten sadece son kararını vererek kazanıyorsun
Clive

28

Zen alt öğesi, bunu theme_preprocess_node işlevine ekleyerek gerçekleştirir:

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

'News' adında bir içerik türünüz varsa, template.php dosyanızda foo_preprocess_node_news adlı bir işlev oluşturabilirsiniz.


Bunu ayrıca ZURB kuruluşunda kendi uygulamamız olan, çok kullanışlı bir kod pasajıyla kullanıyoruz.
Marko Blazekovic

2

Sadece benzer bir sorun yaşadım , bu yüzden google beni bu sayfaya getirdi: düğüm ön işleme fonksiyonum o kadar büyük büyüyordu ki, fonksiyonu çok sayıda dosyaya bölmeyi tercih ettim.

Template.php dosyamda, tüm değiştirici işlevleri içeren benzer bir yaklaşım zaten yaptım ve aynı yöntem burada çok iyi çalıştığından, yaklaşımımı paylaşacağımı düşündüm:

klasörün içindeki dosya kurulumuMYTHEME/preprocess :

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

Zaten sahip node.preprocess.incolmalısın, kendin yaratabilirsin Onları gerçekten nasıl çağırdığınızı oldukça keyfi, ama daha iyi onları tanımlayan ve tüm drupal adlandırma sistemine uygun isimler verin.
bu dosyaların içeriğine doğru!

node.preprocess.inc, işte böyle bir şey yapıyorum:

<?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

}

temelde mevcut düğümün tipini değiştiriyoruz. Geçtiğiniz şey size kalmış; #id, #view_modetüm ihtiyaçlarınızı bağlı olarak.
Bir kez eşleşme olduğunda, belirtilen dosyayı yükler ve tam da bu fonksiyonun içinde yazılmış gibi içeriğine göre hareket eder.

bu includeddosyaların içeriği tam olarak node.preprocess.incdosyaya koyduğunuz gibi görünür , ancak ön işleme işlevini bir daha çağırmazız:

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

temelde bunu istediğiniz kadar dosya ile yapabilirsiniz ve hatta birden fazla anahtarı kademeli olarak düzenleyebilirsiniz; örneğin #view_mode, fullgörüntüleme modu için bir dosyaya ve bir diğeriteaser

Bu yardımcı olur umarım, bir daha kimse bu soruya rastlarsa (:


1

call_user_func()parametreleri referansa göre geçmez. Yani, söz konusu $variablessizin preprocess_foo()sadece orijinal dizinin kopya üzerinde çalışacak işlevlere; nesnelerdeki değişiklikler, kalan oluşturma işlemi sırasında geçerli olmayacaktır.


1

Ana hook_preprocess_node'nizde Sonunda aşağıdaki kodu uygulayın

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

Yani şimdi düğüm türüne göre ön işleme sahip olacaktınız

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.