/** * {@inheritdoc} */ public function submitForm(array &$form, array &$form_state) { $this->taxonomyTerm->delete(); drupal_set_message($this->t('The forum %label and all sub-forums have been deleted.', array('%label' => $this->taxonomyTerm->label()))); watchdog('forum', 'forum: deleted %label and all its sub-forums.', array('%label' => $this->taxonomyTerm->label()), WATCHDOG_NOTICE); $form_state['redirect_route'] = $this->getCancelUrl(); }
/** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $this->taxonomyTerm->delete(); drupal_set_message($this->t('The forum %label and all sub-forums have been deleted.', array('%label' => $this->taxonomyTerm->label()))); $this->logger('forum')->notice('forum: deleted %label and all its sub-forums.', array('%label' => $this->taxonomyTerm->label())); $form_state->setRedirectUrl($this->getCancelUrl()); }
/** * Tests the entity reference field type for referencing content entities. */ public function testContentEntityReferenceItem() { $tid = $this->term->id(); // Just being able to create the entity like this verifies a lot of code. $entity = entity_create('entity_test'); $entity->field_test_taxonomy_term->target_id = $tid; $entity->name->value = $this->randomMachineName(); $entity->save(); $entity = entity_load('entity_test', $entity->id()); $this->assertTrue($entity->field_test_taxonomy_term instanceof FieldItemListInterface, 'Field implements interface.'); $this->assertTrue($entity->field_test_taxonomy_term[0] instanceof FieldItemInterface, 'Field item implements interface.'); $this->assertEqual($entity->field_test_taxonomy_term->target_id, $tid); $this->assertEqual($entity->field_test_taxonomy_term->entity->getName(), $this->term->getName()); $this->assertEqual($entity->field_test_taxonomy_term->entity->id(), $tid); $this->assertEqual($entity->field_test_taxonomy_term->entity->uuid(), $this->term->uuid()); // Change the name of the term via the reference. $new_name = $this->randomMachineName(); $entity->field_test_taxonomy_term->entity->setName($new_name); $entity->field_test_taxonomy_term->entity->save(); // Verify it is the correct name. $term = entity_load('taxonomy_term', $tid); $this->assertEqual($term->getName(), $new_name); // Make sure the computed term reflects updates to the term id. $term2 = entity_create('taxonomy_term', array('name' => $this->randomMachineName(), 'vid' => $this->term->bundle(), 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED)); $term2->save(); $entity->field_test_taxonomy_term->target_id = $term2->id(); $this->assertEqual($entity->field_test_taxonomy_term->entity->id(), $term2->id()); $this->assertEqual($entity->field_test_taxonomy_term->entity->getName(), $term2->getName()); // Delete terms so we have nothing to reference and try again $term->delete(); $term2->delete(); $entity = entity_create('entity_test', array('name' => $this->randomMachineName())); $entity->save(); }
/** * Tests white-listing of methods doesn't interfere with chaining. */ public function testWhiteListChaining() { $node = Node::create(['type' => 'page', 'title' => 'Some node mmk', 'status' => 1, 'field_term' => $this->term->id()]); $node->save(); $this->setRawContent(twig_render_template(drupal_get_path('theme', 'test_theme') . '/templates/node.html.twig', ['node' => $node])); $this->assertText('Sometimes people are just jerks'); }
protected function setUp() { parent::setUp(); $this->mockStandardInstall(); ViewTestData::createTestViews(get_class($this), array('taxonomy_test_views')); $this->term1 = $this->createTerm(); $this->term2 = $this->createTerm(); $node = array(); $node['type'] = 'article'; $node['field_views_testing_tags'][]['target_id'] = $this->term1->id(); $node['field_views_testing_tags'][]['target_id'] = $this->term2->id(); $this->nodes[] = $this->drupalCreateNode($node); $this->nodes[] = $this->drupalCreateNode($node); }
/** * Tests the views_ajax_autocomplete_taxonomy() AJAX callback. */ public function testTaxonomyAutocomplete() { $this->user = $this->drupalCreateUser(array('access content')); $this->drupalLogin($this->user); $base_autocomplete_path = 'taxonomy/autocomplete_vid/' . $this->vocabulary->vid; // Test that no terms returns an empty array. $this->assertIdentical(array(), $this->drupalGetJSON($base_autocomplete_path)); // Test a with whole name term. $label = $this->term1->getName(); $expected = array(array('value' => $label, 'label' => String::checkPlain($label))); $this->assertIdentical($expected, $this->drupalGetJSON($base_autocomplete_path, array('query' => array('q' => $label)))); // Test a term by partial name. $partial = substr($label, 0, 2); $this->assertIdentical($expected, $this->drupalGetJSON($base_autocomplete_path, array('query' => array('q' => $partial)))); }
/** * Returns forum page for a given forum. * * @param \Drupal\taxonomy\TermInterface $taxonomy_term * The forum to render the page for. * * @return array * A render array. */ public function catalogPage(TermInterface $taxonomy_term) { // Get forum details. $taxonomy_term->forums = $this->forumManager->getChildren($this->config('forum.settings')->get('vocabulary'), $taxonomy_term->id()); $taxonomy_term->parents = $this->forumManager->getParents($taxonomy_term->id()); if (empty($taxonomy_term->forum_container->value)) { $build = $this->forumManager->getTopics($taxonomy_term->id(), $this->currentUser()); $topics = $build['topics']; $header = $build['header']; } else { $topics = ''; $header = array(); } return $this->build($taxonomy_term->forums, $taxonomy_term, $topics, $taxonomy_term->parents, $header); }
/** * Tests using entity fields of the taxonomy term reference field type. */ public function testTaxonomyTermReferenceItem() { $tid = $this->term->id(); // Just being able to create the entity like this verifies a lot of code. $entity = entity_create('entity_test'); $entity->field_test_taxonomy->target_id = $this->term->id(); $entity->name->value = $this->randomMachineName(); $entity->save(); $entity = entity_load('entity_test', $entity->id()); $this->assertTrue($entity->field_test_taxonomy instanceof FieldItemListInterface, 'Field implements interface.'); $this->assertTrue($entity->field_test_taxonomy[0] instanceof FieldItemInterface, 'Field item implements interface.'); $this->assertEqual($entity->field_test_taxonomy->target_id, $this->term->id(), 'Field item contains the expected TID.'); $this->assertEqual($entity->field_test_taxonomy->entity->getName(), $this->term->getName(), 'Field item entity contains the expected name.'); $this->assertEqual($entity->field_test_taxonomy->entity->id(), $tid, 'Field item entity contains the expected ID.'); $this->assertEqual($entity->field_test_taxonomy->entity->uuid(), $this->term->uuid(), 'Field item entity contains the expected UUID.'); // Change the name of the term via the reference. $new_name = $this->randomMachineName(); $entity->field_test_taxonomy->entity->setName($new_name); $entity->field_test_taxonomy->entity->save(); // Verify it is the correct name. $term = Term::load($tid); $this->assertEqual($term->getName(), $new_name, 'The name of the term was changed.'); // Make sure the computed term reflects updates to the term id. $term2 = entity_create('taxonomy_term', array('name' => $this->randomMachineName(), 'vid' => $this->term->getVocabularyId(), 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED)); $term2->save(); $entity->field_test_taxonomy->target_id = $term2->id(); $this->assertEqual($entity->field_test_taxonomy->entity->id(), $term2->id(), 'Field item entity contains the new TID.'); $this->assertEqual($entity->field_test_taxonomy->entity->getName(), $term2->getName(), 'Field item entity contains the new name.'); // Test sample item generation. $entity = entity_create('entity_test'); $entity->field_test_taxonomy->generateSampleItems(); $this->entityValidateAndSave($entity); }
/** * Tests output for article properties displayed in both view modes. * * @param \EasyRdf_Graph $graph * The EasyRDF graph object. * @param string $message_prefix * The word to use in the test assertion message. */ protected function assertRdfaArticleProperties($graph, $message_prefix) { // Tags. $expected_value = array('type' => 'uri', 'value' => $this->termUri); $this->assertTrue($graph->hasProperty($this->articleUri, 'http://schema.org/about', $expected_value), "{$message_prefix} tag was found (schema:about)."); // Tag type. // @todo Enable with https://www.drupal.org/node/2072791. //$this->assertEqual($graph->type($this->termUri), 'schema:Thing', 'Tag type was found (schema:Thing).'); // Tag name. $expected_value = array('type' => 'literal', 'value' => $this->term->getName(), 'lang' => 'en'); // @todo Enable with https://www.drupal.org/node/2072791. //$this->assertTrue($graph->hasProperty($this->termUri, 'http://schema.org/name', $expected_value), "$message_prefix name was found (schema:name)."); }
/** * Test saving order sequence doesn't matter. */ public function testEntitySaveOrder() { // The term entity is unsaved here. $term = entity_create('taxonomy_term', array('name' => $this->randomMachineName(), 'vid' => $this->term->bundle(), 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED)); $entity = entity_create('entity_test'); // Now assign the unsaved term to the field. $entity->field_test_taxonomy_term->entity = $term; $entity->name->value = $this->randomMachineName(); // Now save the term. $term->save(); // And then the entity. $entity->save(); $this->assertEqual($entity->field_test_taxonomy_term->entity->id(), $term->id()); }
/** * Tests Quick Edit autocomplete term behavior. */ public function testAutocompleteQuickEdit() { $this->drupalLogin($this->editorUser); $quickedit_uri = 'quickedit/form/node/' . $this->node->id() . '/' . $this->fieldName . '/' . $this->node->language()->getId() . '/full'; $post = array('nocssjs' => 'true') + $this->getAjaxPageStatePostData(); $response = $this->drupalPost($quickedit_uri, 'application/vnd.drupal-ajax', $post); $ajax_commands = Json::decode($response); // Prepare form values for submission. drupalPostAJAX() is not suitable for // handling pages with JSON responses, so we need our own solution here. $form_tokens_found = preg_match('/\\sname="form_token" value="([^"]+)"/', $ajax_commands[0]['data'], $token_match) && preg_match('/\\sname="form_build_id" value="([^"]+)"/', $ajax_commands[0]['data'], $build_id_match); $this->assertTrue($form_tokens_found, 'Form tokens found in output.'); if ($form_tokens_found) { $post = array('form_id' => 'quickedit_field_form', 'form_token' => $token_match[1], 'form_build_id' => $build_id_match[1], $this->fieldName . '[target_id]' => implode(', ', array($this->term1->getName(), 'new term', $this->term2->getName())), 'op' => t('Save')); // Submit field form and check response. Should render back all the terms. $response = $this->drupalPost($quickedit_uri, 'application/vnd.drupal-ajax', $post); $this->assertResponse(200); $ajax_commands = Json::decode($response); $this->setRawContent($ajax_commands[0]['data']); $this->assertLink($this->term1->getName()); $this->assertLink($this->term2->getName()); $this->assertText('new term'); $this->assertNoLink('new term'); // Load the form again, which should now get it back from // PrivateTempStore. $quickedit_uri = 'quickedit/form/node/' . $this->node->id() . '/' . $this->fieldName . '/' . $this->node->language()->getId() . '/full'; $post = array('nocssjs' => 'true') + $this->getAjaxPageStatePostData(); $response = $this->drupalPost($quickedit_uri, 'application/vnd.drupal-ajax', $post); $ajax_commands = Json::decode($response); // The AjaxResponse's first command is an InsertCommand which contains // the form to edit the taxonomy term field, it should contain all three // taxonomy terms, including the one that has just been newly created and // which is not yet stored. $this->setRawContent($ajax_commands[0]['data']); $expected = array($this->term1->getName() . ' (' . $this->term1->id() . ')', 'new term', $this->term2->getName() . ' (' . $this->term2->id() . ')'); $this->assertFieldByName($this->fieldName . '[target_id]', implode(', ', $expected)); // Save the entity. $post = array('nocssjs' => 'true'); $response = $this->drupalPostWithFormat('quickedit/entity/node/' . $this->node->id(), 'json', $post); $this->assertResponse(200); // The full node display should now link to all entities, with the new // one created in the database as well. $this->drupalGet('node/' . $this->node->id()); $this->assertLink($this->term1->getName()); $this->assertLink($this->term2->getName()); $this->assertLink('new term'); } }
/** * Tests validation constraint. */ public function testValidation() { // The term entity is unsaved here. $term = Term::create(array('name' => $this->randomMachineName(), 'vid' => $this->term->bundle(), 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED)); $entity = EntityTest::create(['field_test_taxonomy_term' => ['entity' => $term, 'target_id' => NULL]]); $errors = $entity->validate(); // Using target_id of NULL is valid with an unsaved entity. $this->assertEqual(0, count($errors)); // Using target_id of NULL is not valid with a saved entity. $term->save(); $entity = EntityTest::create(['field_test_taxonomy_term' => ['entity' => $term, 'target_id' => NULL]]); $errors = $entity->validate(); $this->assertEqual(1, count($errors)); $this->assertEqual($errors[0]->getMessage(), 'This value should not be null.'); $this->assertEqual($errors[0]->getPropertyPath(), 'field_test_taxonomy_term.0'); // This should rectify the issue, favoring the entity over the target_id. $entity->save(); $errors = $entity->validate(); $this->assertEqual(0, count($errors)); }
/** * Tests ValidReferenceConstraint with newly created and unsaved entities. */ public function testAutocreateValidation() { // The term entity is unsaved here. $term = Term::create(array('name' => $this->randomMachineName(), 'vid' => $this->term->bundle(), 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED)); $entity = EntityTest::create(['field_test_taxonomy_term' => ['entity' => $term, 'target_id' => NULL]]); $errors = $entity->validate(); // Using target_id of NULL is valid with an unsaved entity. $this->assertEqual(0, count($errors)); // Using target_id of NULL is not valid with a saved entity. $term->save(); $entity = EntityTest::create(['field_test_taxonomy_term' => ['entity' => $term, 'target_id' => NULL]]); $errors = $entity->validate(); $this->assertEqual(1, count($errors)); $this->assertEqual($errors[0]->getMessage(), 'This value should not be null.'); $this->assertEqual($errors[0]->getPropertyPath(), 'field_test_taxonomy_term.0'); // This should rectify the issue, favoring the entity over the target_id. $entity->save(); $errors = $entity->validate(); $this->assertEqual(0, count($errors)); // Test with an unpublished and unsaved node. $title = $this->randomString(); $node = Node::create(['title' => $title, 'type' => 'node', 'status' => NODE_NOT_PUBLISHED]); $entity = EntityTest::create(['field_test_node' => ['entity' => $node]]); $errors = $entity->validate(); $this->assertEqual(1, count($errors)); $this->assertEqual($errors[0]->getMessage(), new FormattableMarkup('This entity (%type: %label) cannot be referenced.', ['%type' => 'node', '%label' => $title])); $this->assertEqual($errors[0]->getPropertyPath(), 'field_test_node.0.entity'); // Publish the node and try again. $node->setPublished(TRUE); $errors = $entity->validate(); $this->assertEqual(0, count($errors)); // Test with a mix of valid and invalid nodes. $unsaved_unpublished_node_title = $this->randomString(); $unsaved_unpublished_node = Node::create(['title' => $unsaved_unpublished_node_title, 'type' => 'node', 'status' => NODE_NOT_PUBLISHED]); $saved_unpublished_node_title = $this->randomString(); $saved_unpublished_node = Node::create(['title' => $saved_unpublished_node_title, 'type' => 'node', 'status' => NODE_NOT_PUBLISHED]); $saved_unpublished_node->save(); $saved_published_node_title = $this->randomString(); $saved_published_node = Node::create(['title' => $saved_published_node_title, 'type' => 'node', 'status' => NODE_PUBLISHED]); $saved_published_node->save(); $entity = EntityTest::create(['field_test_node' => [['entity' => $unsaved_unpublished_node], ['target_id' => $saved_unpublished_node->id()], ['target_id' => $saved_published_node->id()]]]); $errors = $entity->validate(); $this->assertEqual(2, count($errors)); $this->assertEqual($errors[0]->getMessage(), new FormattableMarkup('This entity (%type: %label) cannot be referenced.', ['%type' => 'node', '%label' => $unsaved_unpublished_node_title])); $this->assertEqual($errors[0]->getPropertyPath(), 'field_test_node.0.entity'); $this->assertEqual($errors[1]->getMessage(), new FormattableMarkup('This entity (%type: %label) cannot be referenced.', ['%type' => 'node', '%label' => $saved_unpublished_node->id()])); $this->assertEqual($errors[1]->getPropertyPath(), 'field_test_node.1.target_id'); // Publish one of the nodes and try again. $saved_unpublished_node->setPublished(TRUE); $saved_unpublished_node->save(); $errors = $entity->validate(); $this->assertEqual(1, count($errors)); $this->assertEqual($errors[0]->getMessage(), new FormattableMarkup('This entity (%type: %label) cannot be referenced.', ['%type' => 'node', '%label' => $unsaved_unpublished_node_title])); $this->assertEqual($errors[0]->getPropertyPath(), 'field_test_node.0.entity'); // Publish the last invalid node and try again. $unsaved_unpublished_node->setPublished(TRUE); $errors = $entity->validate(); $this->assertEqual(0, count($errors)); // Test with an unpublished and unsaved comment. $title = $this->randomString(); $comment = Comment::create(['subject' => $title, 'comment_type' => 'comment', 'status' => 0]); $entity = EntityTest::create(['field_test_comment' => ['entity' => $comment]]); $errors = $entity->validate(); $this->assertEqual(1, count($errors)); $this->assertEqual($errors[0]->getMessage(), new FormattableMarkup('This entity (%type: %label) cannot be referenced.', ['%type' => 'comment', '%label' => $title])); $this->assertEqual($errors[0]->getPropertyPath(), 'field_test_comment.0.entity'); // Publish the comment and try again. $comment->setPublished(TRUE); $errors = $entity->validate(); $this->assertEqual(0, count($errors)); // Test with an inactive and unsaved user. $name = $this->randomString(); $user = User::create(['name' => $name, 'status' => 0]); $entity = EntityTest::create(['field_test_user' => ['entity' => $user]]); $errors = $entity->validate(); $this->assertEqual(1, count($errors)); $this->assertEqual($errors[0]->getMessage(), new FormattableMarkup('This entity (%type: %label) cannot be referenced.', ['%type' => 'user', '%label' => $name])); $this->assertEqual($errors[0]->getPropertyPath(), 'field_test_user.0.entity'); // Activate the user and try again. $user->activate(); $errors = $entity->validate(); $this->assertEqual(0, count($errors)); // Test with a temporary and unsaved file. $filename = $this->randomMachineName() . '.txt'; $file = File::create(['filename' => $filename, 'status' => 0]); $entity = EntityTest::create(['field_test_file' => ['entity' => $file]]); $errors = $entity->validate(); $this->assertEqual(1, count($errors)); $this->assertEqual($errors[0]->getMessage(), new FormattableMarkup('This entity (%type: %label) cannot be referenced.', ['%type' => 'file', '%label' => $filename])); $this->assertEqual($errors[0]->getPropertyPath(), 'field_test_file.0.entity'); // Set the file as permanent and try again. $file->setPermanent(); $errors = $entity->validate(); $this->assertEqual(0, count($errors)); }
/** * Generates an action link to display at the top of the forum listing. * * @param string $vid * Vocabulary ID. * @param \Drupal\taxonomy\TermInterface $forum_term * The term for which the links are to be built. * * @return array * Render array containing the links. */ protected function buildActionLinks($vid, TermInterface $forum_term = NULL) { $user = $this->currentUser(); $links = []; // Loop through all bundles for forum taxonomy vocabulary field. foreach ($this->fieldMap['node']['taxonomy_forums']['bundles'] as $type) { if ($this->nodeAccess->createAccess($type)) { $links[$type] = ['#attributes' => ['class' => ['action-links']], '#theme' => 'menu_local_action', '#link' => ['title' => $this->t('Add new @node_type', ['@node_type' => $this->nodeTypeStorage->load($type)->label()]), 'url' => Url::fromRoute('node.add', ['node_type' => $type])]]; if ($forum_term && $forum_term->bundle() == $vid) { // We are viewing a forum term (specific forum), append the tid to // the url. $links[$type]['#link']['localized_options']['query']['forum_id'] = $forum_term->id(); } } } if (empty($links)) { // Authenticated user does not have access to create new topics. if ($user->isAuthenticated()) { $links['disallowed'] = ['#markup' => $this->t('You are not allowed to post new content in the forum.')]; } else { $links['login'] = ['#attributes' => ['class' => ['action-links']], '#theme' => 'menu_local_action', '#link' => array('title' => $this->t('Log in to post new content in the forum.'), 'url' => Url::fromRoute('user.login', [], ['query' => $this->getDestinationArray()]))]; } } return $links; }
/** * Route title callback. * * @param \Drupal\taxonomy\TermInterface $taxonomy_term * The taxonomy term. * * @return string * The term label. */ public function termTitle(TermInterface $taxonomy_term) { return SafeMarkup::xssFilter($taxonomy_term->getName()); }
/** * Generate a menu link plugin definition for a taxonomy term. * * @param \Drupal\taxonomy\TermInterface $term * The taxonomy term for which to build a menu link render array. * @param $base_plugin_definition * The base plugin definition to merge the link with. * * @return array */ protected function buildMenuDefinition(TermInterface $term, $base_plugin_definition) { $term_id = $term->id(); $term_url = $term->urlInfo(); $taxonomy_menu_id = $this->id(); $menu_id = $this->getMenu(); // Determine parent link. // TODO: Evaluate use case of multiple parents (should we make many menu items?) $menu_parent_id = NULL; /** @var $termStorage \Drupal\taxonomy\TermStorageInterface */ $termStorage = $this->entityManager()->getStorage('taxonomy_term'); $parents = $termStorage->loadParents($term_id); $parents = array_values($parents); if (is_array($parents) && count($parents) && !is_null($parents[0]) && $parents[0] != '0') { $menu_parent_id = $this->buildMenuPluginId($parents[0]); } // TODO: Consider implementing a forced weight based on taxonomy tree. // Generate link. $arguments = ['taxonomy_term' => $term_id]; $link = $base_plugin_definition; $link += array('id' => $this->buildMenuPluginId($term), 'title' => $term->label(), 'description' => $term->getDescription(), 'menu_name' => $menu_id, 'metadata' => array('taxonomy_menu_id' => $taxonomy_menu_id, 'taxonomy_term_id' => $term_id), 'route_name' => $term_url->getRouteName(), 'route_parameters' => $term_url->getRouteParameters(), 'load arguments' => $arguments, 'parent' => $menu_parent_id, 'provider' => 'taxonomy_menu', 'class' => 'Drupal\\taxonomy_menu\\Plugin\\Menu\\TaxonomyMenuMenuLink'); return $link; }
/** * Route title callback. * * @param \Drupal\taxonomy\TermInterface $taxonomy_term * The taxonomy term. * * @return string * The term label. */ public function termTitle(TermInterface $taxonomy_term) { return Xss::filter($taxonomy_term->getName()); }
/** * Remove menu entries associate with the vocabulary of this term. * * @param \Drupal\taxonomy\TermInterface $term */ public function removeTaxonomyMenuEntries(TermInterface $term, $rebuild_all = TRUE) { // Load relevant taxonomy menus. $tax_menus = $this->getTermMenusByVocabulary($term->getVocabularyId()); foreach ($tax_menus as $menu) { foreach (array_keys($menu->getLinks([], TRUE)) as $plugin_id) { if (!$rebuild_all) { $plugin_id_parts = explode('.', $plugin_id); $term_id = array_pop($plugin_id_parts); if ($term->id() != $term_id) { continue; } } $this->manager->removeDefinition($plugin_id, FALSE); } } }
/** * Route title callback. * * @param \Drupal\taxonomy\TermInterface $taxonomy_term * The taxonomy term. * * @return array * The term label as a render array. */ public function termTitle(TermInterface $taxonomy_term) { return ['#markup' => $taxonomy_term->getName(), '#allowed_tags' => Xss::getHtmlTagList()]; }
/** * Returns a renderable forum index page array. * * @param array $forums * A list of forums. * @param \Drupal\taxonomy\TermInterface $term * The taxonomy term of the forum. * @param array $topics * The topics of this forum. * @param array $parents * The parent forums in relation this forum. * @param array $header * Array of header cells. * * @return array * A render array. */ protected function build($forums, TermInterface $term, $topics = array(), $parents = array(), $header = array()) { $config = $this->config('forum.settings'); $build = array('#theme' => 'forums', '#forums' => $forums, '#topics' => $topics, '#parents' => $parents, '#header' => $header, '#term' => $term, '#sortby' => $config->get('topics.order'), '#forums_per_page' => $config->get('topics.page_limit')); $build['#attached']['library'][] = 'forum/forum.index'; if (empty($term->forum_container->value)) { $build['#attached']['drupal_add_feed'][] = array('taxonomy/term/' . $term->id() . '/feed', 'RSS - ' . $term->getName()); } return $build; }