プログラムでカスタムモジュールのファイルフィールドを使用してコンテンツタイプを作成する


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とフィールド定義用の配列を使用しました。その方法であなたの仕事をクロスチェックすることができます。
テンケン2013年

回答:


7

これは前の答えを拡張したものなので、それほど多くの答えではありません。

これら2つのリンクは、カスタムモジュールノードタイプにカスタムフィールドを追加するためにシステムが必要とするものを理解するのに非常に役立ちました。

ベスト: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

私が抱えていた問題は、これら(およびオンラインで見つけることができる他のすべての例)が非常に具体的な例であり、自分の使用例の解決策を理解するのに役立つ十分なドキュメントがないことでした。

助けになったのは、機能モジュールを使用してカスタムフィールドの配列を取得することに関するOPへのtenkenのコメントでした。

だから私は機能モジュールをダウンロードして有効にした:https : //drupal.org/project/features

次に、通常のようにDrupalの管理インターフェイスを使用して、モジュールに作成させたいコンテンツタイプのフィールドを作成しました。次に、[構造]> [機能]> [機能の作成]を参照して、機能に偽の名前(「test」を使用)を入力し、コンポーネント領域で[フィールドインスタンス]をクリックして、カスタムフィールドのチェックボックスをオンにします。フィールドはすべてnode- [your node type machine name]-[field name]のような名前が付けられているので、私の場合、画像フィールドが必要だったので、node-novel_section-field_imageでした。

ノードタイプのカスタムフィールドを選択した後、「ダウンロード機能」をクリックして.tarファイルをデスクトップに保存し、それを開き、「test」フォルダーを開いて、test.features.field_base.incとtestを表示しました。 features.field_instance.incを使用して、フィールドに必要な配列を取得します。

次に、私が投稿した最初のリンクで概説されている構造を使用しましたが、その後は完全に機能しました。私のために。

画像フィールドや分類基準フィールドなどに必要な配列構造に関するドキュメントは見つかりませんでした。また、オンラインの他のすべてのチュートリアルやヘルプリクエストは、テキストフィールドなどの特定のものに集中しているようです。

うまくいけば、私が抱えていたのと同じ問題を抱えている誰もがこれを見て、私がしたようにこれらの例と機能モジュールを使用してセットアップ作業を行えるようになるでしょう。

Featuresモジュールのこの機能を指摘してくれた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');
}
?>

非常に詳細な回答をありがとうございましたが、作成後にコンテンツタイプにファイルフィールドを追加するにはどうすればよいですか?
ケニーワイランド2013年

上記のコードを使用しましたが、コンテンツタイプが追加されたと表示されますが、表示されませんadmin/structure/types
Kenny Wyland

1
これを機能させるには、モジュールにhook_form()を実装する必要があります。そうしないと、データベースのnode_typeテーブルを調べると、新しく作成されたタイプが無効になっていることがわかります。hook_form()を実装すると、それがアクティブになるようです(このようになっている理由はわかりませんが、あまり意味がありません)。ところで、これは2番目のコメントに対処します。
user5013 2013年

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.