Добавяне на node weight

Понякога е необходимо да можем да подреждаме нодовете в списъци по собствена преценка или на автора.
Можем лесно да се справим с подреждането като добавим от Manage Fields на съответния вид съдържание поле Тежест (field Weight) тип Integer. Съответно ще въвеждаме 1, 2, n и така нататък за всеки нод в зависимост от желаната позиция, която трябва да заеме в списъка. Най-вероятно това поле не е необходимо да се вижда на front-end, затова от Manage Display го правим Hidden. Също така, при добавянето на нодове от този тип би било добре до полето Тежест да имаме каква е най-голямата стойност на вече въведените от този тип съдържание. Тази дребна (но необходима за редакторите) екстра няма как да добавим без малко код. Необходимо ли е това? Естествено да - няма да се налага да помним какъв е бил тежестта на статия, която сме писали преди месец за да въведем следващата по големина тежест.
За удобство всичко това може да се комплектова като модул (с име node_ext в този случай), който при инсталирането си да добавя гореописаната функционалност. Така ще имаме същата функционалност и на друг сайт без да се налага ръчно да добавяме полета и да настройваме всичко останало.

Първо: При инсталирането на модула (hook_enable()) да създадем въпросното поле field_weight, ако вече не е създадено и да го добавим към съществуващ вид съдържание като article и basic page. Ако искаме същата функционалност на видове съдържание, които сме създали допълнително, добавяме ги към масива $bundles = array('page', 'article');.

/**
 * Implementation of hook_enable().
 */
function node_ext_enable() {
  if (!field_info_field('field_weight')) {
    $field = array(
      'field_name' => 'field_weight', 
      'type' => 'number_integer', 
    );
    field_create_field($field);
 
    $bundles = array('page', 'article');
    // Create the instance on bundles.
    foreach($bundles AS $bundle) {
      $instance = array(
        'field_name' => 'field_weight', 
        'entity_type' => 'node',
        'label' => 'Weight', 
        'bundle' => $bundle, 
        // If you don't set the "required" property then the field wont be required by default.
        'required' => TRUE,
        'widget' => array(
          'type' => 'textfield',
        ), 
      );
      field_create_instance($instance);
    }
  }
}

Използваме field_info_field($field_name) за да проверим дали имаме вече такова поле, field_create_field($field) за да създадем въпросното поле и field_create_instance($instance) за да добавим това поле към article и basic page.

Второ: При добавяне или редактиране на съответния тип съдържание до полето Тежест добавяме последната по големина въведена стойност за този вид съдържание, като имплементираме hook_form_alter(). Като допълнение на това ще попълним следващата по големина тежест в полето.

/**
 * Implements hook_form_alter().
 */
function node_ext_form_alter(&$form, &$form_state, $form_id) {
  if (isset($form['#node_edit_form']) && $form['#node_edit_form'] && isset($form['field_weight'])) {
    //get the bigest number of field_weight
    $weight = db_select('field_data_field_weight', 'w')
      -> fields('w', array('field_weight_value'))
      -> condition('bundle', $form['type']['#value'], '=')
      -> orderBy('field_weight_value', 'DESC')
      -> range(0, 1)
      -> execute() -> fetchField();
 
    if ($weight == FALSE) {
      $weight = '0';
    }
 
    if (empty($form['field_weight']['und'][0]['value']['#default_value'])) {
      $form['field_weight']['und'][0]['value']['#default_value'] = $weight + 1;
    }
    //add suffix to this form field
    $form['field_weight']['#suffix'] = t('Latest Weight for this content type is:') . $weight;
  }
}

Трето: Както се уточнихме по-горе това поле не е необходимо да се вижда извън режим на редакция, затова добавяме и следния код, като имплементираме hook_node_view():

/**
 * Implementation of hook_node_view().
 */
function node_ext_node_view($node, $view_mode, $langcode) {
  //hide the field_weight
  if (isset($node -> field_weight)) {
    hide($node -> content['field_weight']);
  }
}

Като че ли не остана друго. Като ще е модул (и имаме време) може да добавим hook_uninstall() - за да премахнем създаденото с модула поле с field_delete_field('field_weight'), когато деинсталираме модула:

/**
 * Implementation of hook_disable().
 */
function node_ext_disable() {
  if (field_info_field('field_weight')) {
    field_delete_field('field_weight');
  }
}

Готовия модул съм качил в github, откъдето може да бъде изтеглен за ползване, или просто да се разгледа кода - https://github.com/svetlio/node_ext

Това е. Вече във всяко views може да добавим сортиране по полето Тежест във възходящ/низходящ ред.

Categories: 

Comments

Впечатлена съм. Правила съм го, но по най-паешки начин с помнене на макс стойност.

благодаря, пак заповядай :)