web-dev-qa-db-ja.com

D7でhook_installを使用して「プログラムで」新しいコンテンツタイプを作成するにはどうすればよいですか?

モジュール(フルーツ)のコンテンツタイプ(リンゴ)を作成する.INSTALLファイルを作成しようとしています。次のファイル(fruit.install)を、.INFOファイルと.MODULEファイルを含むモジュールフォルダーにドロップしました。 Fruitモジュールを有効にした後、データベースを調べたところ、node_typeテーブルに新しいエントリがないことがわかりました。私は重要なステップを逃しているに違いありませんか?または明らかな間違いを犯したと思いますか?

<?php

/**
 * Implements hook_install()
 */

function fruit_install() {

    // * If the content type does not exist then create it.
    if (!in_array('Apples', node_type_get_names())) {
        $type = array(
            'type' => 'apples',
            'name' => 'Apples',
            'base' => 'node_content',
            'custom' => 1,
            'modified' => 1,
            'locked' => 0,
        );
        $type = node_type_set_defaults($type);
        node_type_save($type);
        // * Set 'Apples' options
        variable_set('node_preview_apples', 0);     // Set 'Preview before submitting' to 'Disabled'
    }
}
2
dbj44

'Apples'コンテンツタイプがnode_typeテーブルに表示されなかった理由は、コードの変更をテストするたびにモジュールをアンインストールしてから再インストールする必要があることに気付かなかったためです。 'Fruit'モジュールを無効にし、モジュールを再度有効にすると、.INSTALLファイルが機能することを期待していました。 andアンインストール(無効にするだけでなく)を無効にしてから、再度有効にする必要があります。どうやら手動でモジュールをシステムテーブルから削除することもできますが、私はそこには行きませんでした。

上記で貼り付けたコードは機能しますが、コンテンツタイプを作成する「正しい」方法ではない場合があります。よく分かりません。私のメソッドは、フィールドUIで同じことを実現する方法を反映しています。新しいコンテンツタイプを追加し、コンテンツタイプオプションを設定し、新しいフィールドを追加してから、それらの新しいフィールドの必要なインスタンスを作成します。これは私には理にかなっているように見えますが、ここで提案されている他の解決策の方が優れている場合があります。

2
dbj44

フォーラムモジュールの機能を確認できます。

  • forum_install() node_options_forum Drupal変数を設定します
  • forum_enable() は、そのフィールド、つまりフォーラムコンテンツタイプで使用する分類フィールドから参照される語彙を作成し、ボディフィールドをコンテンツタイプに追加します

node_type_set_defaults()node_type_save() は呼び出されません。最終的に、forum_enable()node_types_rebuild() を呼び出します。これは、フォーラムモジュール自体から実行されたものを含め、 hook_node_info() の実装を呼び出します。

_  foreach (module_implements('node_info') as $module) {
    $info_array = module_invoke($module, 'node_info');
    foreach ($info_array as $type => $info) {
      $info['type'] = $type;
      $_node_types->types[$type] = node_type_set_defaults($info);
      $_node_types->types[$type]->module = $module;
      $_node_types->names[$type] = $info['name'];
    }
  }

  // …

  if ($rebuild) {
    foreach ($_node_types->types as $type => $type_object) {
      if (!empty($type_object->is_new) || !empty($type_object->disabled_changed)) {
        node_type_save($type_object);
      }
    }
  }
_

ノード本体を除いて、コンテンツタイプにフィールドを追加する必要がない別のモジュールは、すべて blog_install() で行います。

_function blog_install() {
  // Ensure the blog node type is available.
  node_types_rebuild();
  $types = node_type_get_types();
  node_add_body_field($types['blog']);
}
_

つまり、コンテンツタイプの作成には2つの手順が必要です(コンテンツタイプが追加のフィールドを使用しない場合)。

1
kiamlaluno

まず、そのすべてのコードをhook_install()自体の中に入れないでください。代わりに、おそらくインクルードで、コンテンツタイプを作成する別の関数を宣言し、hook_install()から呼び出します。

作成する関数は、 hook_node_info() および hook_form() のインスタンスです。

_//CREATE NEW CONTENT TYPE
function fruit_node_info() {
  return array(
    'event' => array(
    'name' => t('Apple'),
    'base' => 'event',
    'description' => t('An Apple content type'),
    'has_title' => TRUE
    ),
  );
}


function Apple_form($node,$form_state) {
  $form['title'] = array(
    '#type' => 'textfield',
    '#title' => t('event Title'),
    '#default_value' => !empty($node->title) ? $node->title : '',
    '#required' => TRUE,
    '#weight' => -5
  );
  return $form;
}
//END CONTENT TYPE
_

(これは このstackoverflowの質問 から改作されています。私は個人的にテストしていません。)

使用しているコードはhook_node_info()またはhook_form()をまったく使用していないようです。これが、ノードタイプが表示されない理由である可能性があります。また、関数が何も返さず、ノードタイプを保存した後に変数を設定していることに気付きました。これらすべてが問題の原因となっている可能性があります。

0
beth