hook_node_view() и бърз начин да направим достъпно само за регистрирани потребители съдържание

Имаме съдържание, достъпно само за регистрирани потребители, но все пак искаме да покажем на всички поне заглавието. Може би за да предизвикаме интереса им да се регистрират, да станат членове на организацията (сайта). Или по друга причина.

Това може да се направи и с http://drupal.org/project/field_permissions модула, като ще трябва да указваме разрешенията на всеко едно поле във всеки засегнат вид съдържание.

А може да го направим и с наш малък модул.
Практично решение е като направим boolean поле с единичен чекбокс във всеки вид съдържание - за да имаме възможност да посочим кой нод е за членове само при създаването му, и съвсем малко код в наш модул. Когато е отметнат нода е защитен, когато не е нода е достъпен за всички.
За да е съвсем лесно, ще ползваме част от кода на node_ext (който дефинира поле и го пресъздава във всеки посочен вид съдържание в сайта). Това ще спести работата по създаването на поле ръчно и използването му във всеки нод. Така при инсталиране на модула полето ще се създаде във всеки вид съдържание автоматично. Ще се погрижим също при изключване на модула да премахнем полето , което той създава.

Първо съдаваме полето field_private като един чекбокс.

/**
 * Implementation of hook_enable().
 */
function my_module_enable() {
  // Check if our field is not already created.
  if (!field_info_field('field_private')) {
 
    $field = array(
      'field_name' => 'field_private', 
      'type' => 'list_boolean',
      'widget' => array(
        'type' => 'options_onoff',
      ),
      'settings' => array(
        'label' => t('Private'),
        'no_ui' => FALSE,
      ),
    );
    field_create_field($field);
 
    $bundles = array('page', 'news', 'event');
    // Create the instance on bundles.
    foreach($bundles AS $bundle) {
      $instance = array(
        'field_name' => 'field_private', 
        'entity_type' => 'node',
        'label' => 'Private', 
        'bundle' => $bundle,
        'required' => FALSE,
        'widget' => array(
          'type' => 'options_onoff',
          'settings' => array(
            'allowed_values' => array(
              0 => 'no',
              1 => 'yes'
            ),
          ),
        ), 
      );
      field_create_instance($instance);
    }
  }
}
 
/**
 * Implementation of hook_disable().
 */
function my_module_disable() {
  if (field_info_field('field_private')) {
    field_delete_field('field_private');
  }
}

Дотук е частта с полето, което се грижи как да укажем кой нод да е достъпен само за регистрирани потребители. Както уточних в началото, заглавието на всички нодове ще са достъпни за всички. Но вместо съдържанието на самия нод, под заглавието на защитените ще изведем надпис с подходящо съобщение.

Следва кода, който следи за неприкосновеността на нашето защитено съдържание.

/**
 * Implements hook_node_view().
 *
 */
function my_module_node_view($node, $view_mode, $langcode) {
  global $user;
 
  if (isset($node -> field_private) && @$node -> field_private['und'][0]['value'] == 1 && $user -> uid == 0) {
    //remove all node content
    unset($node -> content);
    //add message
    $node -> content['private_content']['#markup'] =  '<p>' . t('This is a private content. Please !login first.', array('!login' => l(t('Log in'), 'user/login'))) . '</p>';
  }
}

Това е.

Първата и по-голяма часто от кода би се оказала излишна, ако си създадем това поле през field UI. Остава hook_node_view(), където на практика се решава какво при какви условия да се покаже.

Ще покажа и алтернативен начин, който е в разрез с добрите практики, Не го препоръчвам и е пример как Не трябва да се прави по ред причини.

Следния код е предназначен за node.tpl.php

    global $user;
 
    // We hide the comments and links now so that we can render them later.
    hide($content['comments']);
    hide($content['links']);
 
    if (isset($node -> field_private) && @$node -> field_private['und'][0]['value'] == 1 && $user -> uid == 0) {
      print '<p>' . t('This is a private content. Please !login first.', array('!login' => l(t('Log in'), 'user/login'))) . '</p>';
    }
    else {
      print render($content);
 
      print render($content['links']);
      print render($content['comments']);
    }

Той заменя частта

      // We hide the comments and links now so that we can render them later.
      hide($content['comments']);
      hide($content['links']);
      print render($content);

като включва проверка на полето field_private.

На практика резултата е един и същ. Но това е само на пръв поглед.

Всички hook и функции на друпал в Tags могат да бъдат разгледани в подробности и тук, но както се досещате това вече е направено на http://api.drupal.org - потърсете за тях в полето за търсене там.

Category: