web-dev-qa-db-ja.com

Json-分類用語を含むノードのインポート

私はDrupal 8.3.6を実行しています。typo3から発信されたjsonストリームをインポートしようとしています。これは基本的にこの形式のブログ投稿のリストです。

[{
    "id": "1",
    "title": "Title",
    "bodytext": "Bodytext with html Mark-Up",
    "datetime": "1269437640",
    "keywords": "term1, term2, term3, term4,..."
},{
    "id": "2",
    "title": "Title 2",
    "bodytext": "Another Bodytext with html Mark-Up",
    "keywords": "term6, term3, term9, term7,..."
}]

私は これらの指示 に従って小さなモジュールを考え出しました、これはタイトルと本文に対してうまく機能します:

protected function createBlog(string $json) {
    $jsonout = json_decode($json, TRUE);

    foreach ($jsonout as $blog) {

      $node = Node::create(array(
        'type' => 'blog',
        'langcode' => 'de',
        'uid' => '1',
        'status' => 1,
        'title' => $blog['title'],
        'body' => ['value' => $blog['bodytext'], 'format' => 'full_html'],
      ));

      $node->save();
    }
  }

ただし、ノードによって作成および参照される用語を取得するのに苦労しています。私はこのようなものを試しましたが、うまくいきません:

protected function createBlog(string $json) {
    $jsonout = json_decode($json, TRUE);

    foreach ($jsonout as $blog) {
      foreach ($blog['keywords'] as $tag) { // Loop through each blog entries keywords and create terms
        $term = Term::create(array(
          'name' => $tag,
          'vid' => 'tags',
        ))->save();
      }

      $node = Node::create(array(
        'type' => 'blog',
        'langcode' => 'de',
        'uid' => '1',
        'status' => 1,
        'title' => $blog['title'],
        'field_tags' => $blog['keywords'], // I would need to have the terms from above in an array to add them here, right?
        'body' => ['value' => $blog['bodytext'], 'format' => 'full_html'],
      ));

      $node->save();
    }
  }

用語が作成されず、作成されたとしても、それらをノードに関連付ける方法がわかりません。また、それが機能する場合、用語の作成時に、用語がすでに存在するかどうかをチェックしないという問題があります。ノードが同じ用語を持つ可能性があるため、これは必要になります。

私のアプローチでこれを達成することは可能ですか?はいの場合、方法を教えてください。また、migrate_plusを調べましたが、かなり複雑でした。

何か助けていただければ幸いです!

そして私

2
andir

残りの依存関係がどのように設定されているかがわからないのですが、最初に気付いたのは、keywordsソースフィールドがカンマ区切りの単一の文字列であるということですが、それを値の配列として扱っていますあなたのプロセッサ。多分このようなもの:

protected function createBlog(string $json)
{
    $jsonout = json_decode($json, TRUE);

    foreach ($jsonout as $blog) {
        $newTags = explode(', ', $blog['keywords']);
        $newTagIDs = [];
        foreach ($newTags as $tag) {
            $newTagIDs[] = Term::create(array(
                'name' => $tag,
                'vid' => 'tags'
            ))->save();
        }

        $node = Node::create(array(
            'type' => 'blog',
            'langcode' => 'de',
            'uid' => '1',
            'status' => 1,
            'title' => $blog['title'],
            'field_tags' => $newTagIDs,
            'body' => ['value' => $blog['bodytext'], 'format' => 'full_html']
        ));

        $node->save();
    }
}

ただし、このアプローチでは同じ用語の複数のコピーが作成されます。 migrate_plusモジュールのEntity Lookupプラグインはいくつかの助けを提供するかもしれません:

// $this->entityManager is a dependency-injected instance of Drupal\Core\Entity\EntityManagerInterface
$query = $this->entityManager->getStorage('taxonomy_term')
    ->getQuery()
    ->condition('name', $termNameToLookup)
    ->condition('vid', $vocabularyToLookup);
$results = $query->execute();
if (empty($results)) {
    // term doesn't exist in that vocabulary; should add it
} else {
    // the term already exists in that vocabulary; do something with it
}
1
mounty

キャンベルベルテシのチュートリアルを紹介してd8の移行を開始してくれたmountyに感謝します。 https://ohthehugemanatee.org/blog/2017/06/07/stop-waiting-for-feeds-module- how-to-import-remote-feeds-in-drupal-8 /

それは祝福です。また、d8ドキュメントも役立ちます: https://www.drupal.org/docs/8/api/migrate-api/migrate-process-plugins/migrate-process-overview

移行したタグのリストを取得するための重要な部分は、次のパイプラインです。

field_tags:
    -
      plugin: explode
      source: keywords
      delimiter: ','
    -
      plugin: entity_generate
      lookupBundleKey: vid
      lookupBundle: tags

Explodeプラグインはリストからタグを取得し、entity_generateプラグインはエンティティが存在するかどうかを確認します。そうでない場合、エンティティが作成されます。次に、タグがノードに追加されます。私のインポート用のymlファイル全体:

id: blog_importer
label: 'Blog Importer'
status: true

source:
  plugin: url
  data_fetcher_plugin: http
  urls: 'url/file.json'
  data_parser_plugin: json

  item_selector: blog-entry
  fields:
    -
      name: bid
      label: 'Blog Post ID'
      selector: uid
    -
      name: title
      label: Title
      selector: title
    -
      name: body
      label: Body
      selector: bodytext
    -
      name: keywords
      label: Keywords
      selector: keywords

  ids:
    bid:
      type: integer

destination:
  plugin: 'entity:node'

process:
  title: title
  'body/format':
    plugin: default_value
    default_value: "full_html"
  'body/value': body
  field_tags:
    -
      plugin: explode
      source: keywords
      delimiter: ','
    -
      plugin: entity_generate
      lookupBundleKey: vid
      lookupBundle: tags
  status:
    plugin: default_value
    default_value: 1
  type:
    plugin: default_value
    default_value: toppik_blog
0
andir