การสร้างชนิดเนื้อหาที่มีฟิลด์ไฟล์ในโมดูลที่กำหนดเองโดยทางโปรแกรม


9

ฉันกำลังเขียนโมดูลที่กำหนดเองซึ่งฉันเคยทำมาก่อน แต่นี่เป็นครั้งแรกที่ฉันพยายามสร้างประเภทเนื้อหาที่มีฟิลด์ ฉันใช้งานhook_node_infoและประเภทเนื้อหาแสดงขึ้นในรายการประเภทเนื้อหาในรายการดรอปดาวน์จาก admin_menu อย่างไรก็ตามเมื่อฉันเรียกดูจะadmin/structure/typesไม่อยู่ในรายการ

ฉันติดตั้งhook_installและหยิบรหัสที่ฉันพบในคำถาม SO อื่น ฉันมีรหัสพิมพ์ข้อมูลแก้ไขข้อบกพร่องบางอย่างลงในบันทึกข้อผิดพลาดของฉันและมันก็ดูเหมือนว่ามันทำงานได้ทั้งหมด แต่เมื่อฉันเรียกดูโครงสร้างเนื้อหาประเภทมันไม่แสดงเขตข้อมูลที่ฉันเพิ่ม

นี่คือตะขอ:

function mymod_node_info() {
  return array(
    'mymod_content' => array(
      'name' => t('My Mod'),
      'base' => 'mymod_content',
      'description' => t('A Description'),
    )
  );
}

function mymod_install() {
    error_log('mymod_install');
    $types = node_type_get_types();

    if ( ! field_info_field('field_mymod_myfile') ) {
        $field = array(
            'field_name' => 'field_mymod_myfile',
            'type' => 'file',
        );
        $created_field = field_create_field($field);
        error_log('---- field_create_field -----');
        error_log(var_export($created_field, true));
    }

    $instance = array(
        'field_name' => 'field_mymod_myfile',
        'entity_type' => 'mymod_content',
        'bundle' => 'mymod_content',
        'required' => TRUE,
    );
    $created_instance = field_create_instance($instance);
    error_log('---- field_create_instance -----');
    error_log(var_export($created_instance, true));
}

ฉันสามารถดูตารางที่เรียกว่าfield_data_field_mymod_myfileในฐานข้อมูลดังนั้นฉันรู้ว่าส่วนแรกทำงานได้ อย่างไรก็ตามตารางนั้นว่างเปล่า

บันทึกข้อผิดพลาดแสดงfield_create_instance()วิธีการคืนค่านี้:

array (
  'field_name' => 'field_mymod_myfile',
  'entity_type' => 'mymod_content',
  'bundle' => 'mymod_content',
  'required' => true,
  'field_id' => '5',
)

เหตุใดเขตข้อมูลของฉันจึงไม่ปรากฏในประเภทเนื้อหานี้


1
คุณไม่ชอบคุณสมบัติหรือไม่ ฉันคิดว่ามันง่ายที่สุดในการสร้างประเภทเนื้อหาโดยใช้ FieldUI จากนั้นส่งออกคุณสมบัติไปยัง "คุณสมบัติ" ที่กำหนดเอง (โมดูล) ... มันแค่ทำให้อาร์เรย์ใช้ hook_info ที่คุณมีที่นี่ - และอาร์เรย์สำหรับคำจำกัดความของฟิลด์ คุณสามารถตรวจสอบงานของคุณได้
tenken

คำตอบ:


7

นี่ไม่ใช่คำตอบที่มากนักเพราะเป็นการขยายคำตอบก่อนหน้า

ฉันพบว่าลิงก์ทั้งสองนี้มีประโยชน์อย่างมากในการหาว่าระบบต้องการให้ฟิลด์ที่กำหนดเองถูกเพิ่มลงในประเภทโหนดโมดูลที่กำหนดเองของคุณได้อย่างไร

ดีที่สุด: http://www.sitepoint.com/creating-a-new-drupal-node-type/

ข้อมูลเพิ่มเติมที่ดี: http://public-action.org/content/drupal-7-field-api-drupal-7-adding-custom-content-type-custom-fields-field-api

ปัญหาที่ฉันมีคือสิ่งเหล่านี้ (และตัวอย่างอื่น ๆ ที่ฉันสามารถหาได้ทางออนไลน์) เป็นตัวอย่างที่เฉพาะเจาะจงมากโดยไม่มีเอกสารเพียงพอที่จะช่วยฉันหาวิธีแก้ปัญหากรณีการใช้งานของตัวเอง

สิ่งที่ช่วยได้คือข้อคิดเห็นของ tenken ที่มีต่อ OP เกี่ยวกับการใช้โมดูลฟีเจอร์เพื่อรับอาร์เรย์สำหรับฟิลด์ที่กำหนดเอง

ดังนั้นฉันจึงดาวน์โหลดโมดูลคุณลักษณะและเปิดใช้งาน: https://drupal.org/project/features

จากนั้นฉันสร้างฟิลด์ตามประเภทเนื้อหาของฉันโดยใช้ส่วนติดต่อผู้ดูแลระบบใน Drupal อย่างที่คุณต้องการโดยปกติแล้วฉันต้องการให้โมดูลสร้างขึ้น จากนั้นฉันเรียกดูโครงสร้าง> คุณสมบัติ> สร้างคุณสมบัติและใส่ชื่อปลอม (ฉันใช้ "ทดสอบ") สำหรับคุณสมบัติแล้วคลิกที่ "พื้นที่อินสแตนซ์ของฟิลด์" จากนั้นคลิกที่ "อินสแตนซ์ของฟิลด์" และเลือกช่องที่กำหนดเอง เขตข้อมูลมีชื่อบางอย่างเช่น node- [ชื่อเครื่องของคุณชนิดโหนด] - [ชื่อเขตข้อมูล] ดังนั้นในกรณีของฉันตั้งแต่ฉันต้องการเขตข้อมูลภาพมันเป็น node-novel_section-field_image

หลังจากเลือกฟิลด์ที่กำหนดเองสำหรับประเภทโหนดของฉันฉันเพียงคลิกที่ "คุณสมบัติการดาวน์โหลด" และบันทึกไฟล์. tar ลงบนเดสก์ท็อปของฉันเปิดมันเปิดโฟลเดอร์ "test" จากนั้นดู test.features.field_base.inc และทดสอบ features.field_instance.inc เพื่อรับอาร์เรย์ที่ฉันต้องการสำหรับสาขาของฉัน

จากนั้นฉันก็ใช้โครงสร้างที่ระบุไว้ในลิงค์แรกที่ฉันโพสต์และหลังจากนั้นมันก็ทำงานได้อย่างสมบูรณ์ สำหรับฉัน.

ฉันไม่พบเอกสารใด ๆ เกี่ยวกับโครงสร้างอาร์เรย์ที่จำเป็นสำหรับสิ่งต่าง ๆ เช่นเขตข้อมูลรูปภาพและเขตข้อมูลอ้างอิง taxonomy และดูเหมือนว่าบทเรียนอื่น ๆ ทั้งหมดและขอความช่วยเหลือออนไลน์จะเน้นไปที่สิ่งที่เฉพาะเจาะจงเช่นเขตข้อมูลข้อความ

หวังว่าทุกคนที่มีปัญหาแบบเดียวกันกับที่ฉันเคยเห็นจะเห็นสิ่งนี้และสามารถทำให้การตั้งค่าของพวกเขาทำงานโดยใช้ตัวอย่างเหล่านี้และโมดูลคุณลักษณะอย่างที่ฉันทำ

ขอบคุณ tenken ที่ชี้ให้เห็นการทำงานของโมดูลคุณสมบัตินี้ฉันไม่เคยใช้มันและไม่ทราบว่าจะทำเช่นนั้น


4

รหัสนี้จะถูกสร้างประเภทเนื้อหาใหม่ที่ควรเพิ่มลงในไฟล์. install

การเพิ่ม hook_install ():

<?php
function your_module_name_install() {
  // use get_t() to get the name of our localization function for translation
  // during install, when t() is not available.
  $t = get_t();

  // Define the node type.
  $node_example = array(
    'type' => 'node_example',
    'name' => $t('Example Node'),
    'base' => 'node_content',
    'description' => $t('This is an example node type with a few fields.'),
    'body_label' => $t('Example Description')
  );

  // Complete the node type definition by setting any defaults not explicitly
  // declared above.
  // http://api.drupal.org/api/function/node_type_set_defaults/7
  $content_type = node_type_set_defaults($node_example);
  node_add_body_field($content_type);

  // Save the content type
  node_type_save($content_type);
}
?>

คุณควรสร้างข้อความ drupal และเขียนเหตุการณ์นี้ลงในบันทึก:

<?php
function your_module_name_install() {
  $t = get_t();
  $node_example = array(
    'type' => 'node_example',
    'name' => $t('Example Node'),
    'base' => 'node_content',
    'description' => $t('This is an example node type with a few fields.'),
    'body_label' => $t('Example Description')
  );
  $content_type = node_type_set_defaults($node_example);
  node_add_body_field($content_type);
// Check if we create content type or update.
  $status = node_type_save($content_type);
// Replacement rule for the messages.
  $t_args = array('%name' => $content_type->name);
  if ($status == SAVED_UPDATED) { // update case
    drupal_set_message($t('The content type %name has been updated.', $t_args));
  } 
  elseif ($status == SAVED_NEW) { // create case
    drupal_set_message($t('The content type %name has been added.', $t_args));
    watchdog('node', 'Added content type %name.', $t_args, WATCHDOG_NOTICE, l($t('view'), 'admin/structure/types')); 
  }
}
?>

ระบุ hook_uninstall () เพื่อลบประเภทเนื้อหาของคุณ :

<?php
function your_module_name_uninstall() {
  // Gather all the example content that might have been created while this
  // module was enabled.  Simple selects still use db_query().
  // http://api.drupal.org/api/function/db_query/7
  $sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
  $result = db_query($sql, array(':type' => 'node_example'));
  $nids = array();
  foreach ($result as $row) {
    $nids[] = $row->nid;
  }
  // Delete all the nodes at once
  // http://api.drupal.org/api/function/node_delete_multiple/7
  node_delete_multiple($nids);
  // Delete our content type
  // http://api.drupal.org/api/function/node_type_delete/7
  node_type_delete('node_example');
}
?>

ขอบคุณสำหรับการตอบกลับอย่างละเอียด แต่ฉันจะเพิ่มฟิลด์ไฟล์ลงในประเภทเนื้อหาหลังจากที่สร้างขึ้นได้อย่างไร
Kenny Wyland

ฉันใช้รหัสของคุณด้านบนและระบุว่ามีการเพิ่มประเภทเนื้อหา แต่ไม่ปรากฏขึ้นadmin/structure/types
Kenny Wyland

1
เพื่อให้สิ่งนี้ใช้งานได้คุณจะต้องใช้ hook_form () ในโมดูลของคุณมิฉะนั้นหากคุณดูในตาราง node_type ในฐานข้อมูลคุณจะสังเกตเห็นว่าประเภทที่สร้างขึ้นใหม่ของคุณถูกปิดใช้งาน การใช้งาน hook_form () ดูเหมือนว่าจะเปิดใช้งาน (ทำไมเป็นแบบนี้ฉันไม่มีความคิดและไม่เข้าท่ามากนัก) วิธีนี้จะแสดงความคิดเห็นที่สองของคุณตามวิธี
user5013

1

โพสต์นี้ค่อนข้างล้าสมัย แต่ถ้าช่วยได้ฉันพบว่าบทความนี้มีความชัดเจนมาก มันแสดงให้คุณเห็นวิธีการสร้างประเภทเนื้อหาใหม่ทีละขั้นตอน

ลิงก์ไปยังบทช่วยสอน

<?php

/**
 * Implements hook_install().
 */
function book_install()
{

    $t = get_t();

    // Step 1 - Define the custom content type

    $content_type = array(

        'type'          => 'book',
        'name'          => $t('Book'),
        'description'   => $t('Create a new book'),
        'title_label'   => $t('Book title'),
        'base'          => 'node_content',
        'custom'        => TRUE,

    );

    $node_type = node_type_set_defaults($content_type);

    node_type_save($node_type);

    // Step 2 - Create new fields

    $fields = array(

        // Author’s name

        'book_author_name'  => array(

            'field_name'    => 'book_author_name',
            'type'          => 'text',
            'cardinality'   => 1,

        ),

        // Description

        'book_description'  => array(

            'field_name'    => 'book_description',
            'type'          => 'text_long',
            'cardinality'   => 1,

        ),

    );

    foreach( $fields as $field ) {

        field_create_field($field);

    }

    // Step 3 - Attach fields to content type

    $instances = array(

        // Author’s name

        'book_author_name'  => array(

            'field_name'   => 'book_author_name',
            'label'        => $t('Author Name'),
            'required'     => TRUE,
            'widget'       => array(
                'type'  => 'text_textfield'
            ),

        ),

        // Description

        'book_description'  => array(

            'field_name'   => 'book_description',
            'label'        => $t('Description'),
            'required'     => TRUE,
            'widget'       => array(
                'type'  => 'text_textarea'
            ),

        ),

    );

    foreach( $instances as $instance ) { // Loop through our instances

        $instance['entity_type']   = 'node';
        $instance['bundle']        = 'book'; // Attach the instance to our content type

        field_create_instance($instance);

    }

}

โปรดระบุคำพูดที่เกี่ยวข้องในคำตอบของคุณ
Pierre.Vriens
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.