/** * {@inheritdoc} */ public function build() { $this->view->display_handler->preBlockBuild($this); // We ask ViewExecutable::buildRenderable() to avoid creating a render cache // entry for the view output by passing FALSE, because we're going to cache // the whole block instead. if ($output = $this->view->buildRenderable($this->displayID, [], FALSE)) { // Override the label to the dynamic title configured in the view. if (empty($this->configuration['views_label']) && $this->view->getTitle()) { $output['#title'] = ['#markup' => $this->view->getTitle(), '#allowed_tags' => Xss::getHtmlTagList()]; } // Before returning the block output, convert it to a renderable array // with contextual links. $this->addContextualLinks($output); // Block module expects to get a final render array, without another // top-level #pre_render callback. So, here we make sure that Views' // #pre_render callback has already been applied. $output = View::preRenderViewElement($output); // When view_build is empty, the actual render array output for this View // is going to be empty. In that case, return just #cache, so that the // render system knows the reasons (cache contexts & tags) why this Views // block is empty, and can cache it accordingly. if (empty($output['view_build'])) { $output = ['#cache' => $output['#cache']]; } return $output; } return array(); }
/** * {@inheritdoc} */ public function build() { $this->view->display_handler->preBlockBuild($this); if ($output = $this->view->buildRenderable($this->displayID, [], FALSE)) { // Override the label to the dynamic title configured in the view. if (empty($this->configuration['views_label']) && $this->view->getTitle()) { $output['#title'] = ['#markup' => $this->view->getTitle(), '#allowed_tags' => Xss::getHtmlTagList()]; } // Before returning the block output, convert it to a renderable array // with contextual links. $this->addContextualLinks($output); return $output; } return array(); }
/** * Overrides \Drupal\views\Plugin\views\display\PathPluginBase::execute(). */ public function execute() { parent::execute(); // And now render the view. $render = $this->view->render(); // First execute the view so it's possible to get tokens for the title. // And the title, which is much easier. // @todo Figure out how to support custom response objects. Maybe for pages // it should be dropped. if (is_array($render)) { $render += array('#title' => ['#markup' => $this->view->getTitle(), '#allowed_tags' => Xss::getHtmlTagList()]); } return $render; }
/** * Route title callback. * * @param \Drupal\user\UserInterface $user * The user account. * * @return string|array * The user account name as a render array or an empty string if $user is * NULL. */ public function userTitle(UserInterface $user = NULL) { return $user ? ['#markup' => $user->getUsername(), '#allowed_tags' => Xss::getHtmlTagList()] : ''; }
/** * {@inheritdoc} */ protected function getRevisionDescription(ContentEntityInterface $revision, $is_default = FALSE) { /** @var \Drupal\Core\Entity\ContentEntityInterface|\Drupal\user\EntityOwnerInterface|\Drupal\Core\Entity\RevisionLogInterface $revision */ if ($revision instanceof RevisionLogInterface) { // Use revision link to link to revisions that are not active. $date = $this->dateFormatter->format($revision->getRevisionCreationTime(), 'short'); $link = $revision->toLink($date, 'revision'); // @todo: Simplify this when https://www.drupal.org/node/2334319 lands. $username = ['#theme' => 'username', '#account' => $revision->getRevisionUser()]; $username = $this->renderer->render($username); } else { $link = $revision->toLink($revision->label(), 'revision'); $username = ''; } $markup = ''; if ($revision instanceof RevisionLogInterface) { $markup = $revision->getRevisionLogMessage(); } if ($username) { $template = '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}'; } else { $template = '{% trans %} {{ date }} {% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}'; } $column = ['data' => ['#type' => 'inline_template', '#template' => $template, '#context' => ['date' => $link->toString(), 'username' => $username, 'message' => ['#markup' => $markup, '#allowed_tags' => Xss::getHtmlTagList()]]]]; return $column; }
/** * 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()]; }
/** * Route title callback. * * @param \Drupal\system\MenuInterface $menu * The menu entity. * * @return array * The menu label as a render array. */ public function menuTitle(MenuInterface $menu) { return ['#markup' => $menu->label(), '#allowed_tags' => Xss::getHtmlTagList()]; }
/** * Generates an overview table of older revisions of a node. * * @param \Drupal\node\NodeInterface $node * A node object. * * @return array * An array as expected by drupal_render(). */ public function revisionOverview(NodeInterface $node) { $account = $this->currentUser(); $langcode = $node->language()->getId(); $langname = $node->language()->getName(); $languages = $node->getTranslationLanguages(); $has_translations = count($languages) > 1; $node_storage = $this->entityManager()->getStorage('node'); $type = $node->getType(); $build['#title'] = $has_translations ? $this->t('@langname revisions for %title', ['@langname' => $langname, '%title' => $node->label()]) : $this->t('Revisions for %title', ['%title' => $node->label()]); $header = array($this->t('Revision'), $this->t('Operations')); $revert_permission = ($account->hasPermission("revert {$type} revisions") || $account->hasPermission('revert all revisions') || $account->hasPermission('administer nodes')) && $node->access('update'); $delete_permission = ($account->hasPermission("delete {$type} revisions") || $account->hasPermission('delete all revisions') || $account->hasPermission('administer nodes')) && $node->access('delete'); $rows = array(); $vids = $node_storage->revisionIds($node); $latest_revision = TRUE; foreach (array_reverse($vids) as $vid) { /** @var \Drupal\node\NodeInterface $revision */ $revision = $node_storage->loadRevision($vid); // Only show revisions that are affected by the language that is being // displayed. if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)->isRevisionTranslationAffected()) { $username = ['#theme' => 'username', '#account' => $revision->getRevisionAuthor()]; // Use revision link to link to revisions that are not active. $date = $this->dateFormatter->format($revision->revision_timestamp->value, 'short'); if ($vid != $node->getRevisionId()) { $link = $this->l($date, new Url('entity.node.revision', ['node' => $node->id(), 'node_revision' => $vid])); } else { $link = $node->link($date); } $row = []; $column = ['data' => ['#type' => 'inline_template', '#template' => '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}', '#context' => ['date' => $link, 'username' => $this->renderer->renderPlain($username), 'message' => ['#markup' => $revision->revision_log->value, '#allowed_tags' => Xss::getHtmlTagList()]]]]; // @todo Simplify once https://www.drupal.org/node/2334319 lands. $this->renderer->addCacheableDependency($column['data'], $username); $row[] = $column; if ($latest_revision) { $row[] = ['data' => ['#prefix' => '<em>', '#markup' => $this->t('Current revision'), '#suffix' => '</em>']]; foreach ($row as &$current) { $current['class'] = ['revision-current']; } $latest_revision = FALSE; } else { $links = []; if ($revert_permission) { $links['revert'] = ['title' => $this->t('Revert'), 'url' => $has_translations ? Url::fromRoute('node.revision_revert_translation_confirm', ['node' => $node->id(), 'node_revision' => $vid, 'langcode' => $langcode]) : Url::fromRoute('node.revision_revert_confirm', ['node' => $node->id(), 'node_revision' => $vid])]; } if ($delete_permission) { $links['delete'] = ['title' => $this->t('Delete'), 'url' => Url::fromRoute('node.revision_delete_confirm', ['node' => $node->id(), 'node_revision' => $vid])]; } $row[] = ['data' => ['#type' => 'operations', '#links' => $links]]; } $rows[] = $row; } } $build['node_revisions_table'] = array('#theme' => 'table', '#rows' => $rows, '#header' => $header, '#attached' => array('library' => array('node/drupal.node.admin'))); return $build; }
/** * Description filter helper. * * @param $string * The string with raw HTML in it. It will be stripped of everything that * can cause an XSS attack. * * @return string * An XSS safe version of $string, or an empty string if $string is not * valid UTF-8. * * @see \Drupal\Component\Utility\Xss::filter() */ public static function descriptionFilter($string) { return parent::filter($string, ['img'] + Xss::getHtmlTagList()); }
/** * Route title callback. * * @param \Drupal\aggregator\FeedInterface $aggregator_feed * The aggregator feed. * * @return array * The feed label as a render array. */ public function feedTitle(FeedInterface $aggregator_feed) { return ['#markup' => $aggregator_feed->label(), '#allowed_tags' => Xss::getHtmlTagList()]; }
/** * Route title callback. * * @param \Drupal\rdf_entity\RdfInterface $rdf_entity * The rdf entity. * * @return array * The rdf entity label as a render array. */ public function rdfTitle(RdfInterface $rdf_entity) { return ['#markup' => $rdf_entity->getName(), '#allowed_tags' => Xss::getHtmlTagList()]; }
/** * Altered title callback for the navigation menu edit form. * * @param \Drupal\og_menu\OgMenuInstanceInterface $ogmenu_instance * The OG Menu instance that is being edited. * * @return array * The title as a render array. * * @see \Drupal\custom_page\Routing\RouteSubscriber::alterRoutes() */ public function editFormTitle(OgMenuInstanceInterface $ogmenu_instance) { // Provide a custom title for the OG Menu instance edit form. The default // menu is suitable for webmasters, but we need a simpler title since this // form is exposed to regular visitors. $group = $ogmenu_instance->og_audience->entity; return ['#markup' => t('Edit navigation menu of the %group @type', ['%group' => $ogmenu_instance->label(), '@type' => $group->bundle()]), '#allowed_tags' => Xss::getHtmlTagList()]; }
protected function getRevisionDescription(ContentEntityInterface $revision, $is_current = FALSE) { /** @var \Drupal\Core\Entity\ContentEntityInterface|\Drupal\user\EntityOwnerInterface $revision */ if ($revision instanceof EntityOwnerInterface) { $username = ['#theme' => 'username', '#account' => $revision->getOwner()]; } else { $username = ''; } if ($revision instanceof ExpandedEntityRevisionInterface) { // Use revision link to link to revisions that are not active. $date = $this->dateFormatter()->format($revision->getRevisionCreationTime(), 'short'); if (!$is_current) { $link = $this->l($date, $revision->urlInfo('revision')); } else { $link = $revision->link($date); } } else { $link = $revision->link($revision->label(), 'revision'); } $markup = ''; if ($revision instanceof EntityRevisionLogInterface) { $markup = $revision->getRevisionLog(); } if ($username) { $template = '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}'; } else { $template = '{% trans %} {{ date }} {% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}'; } $column = ['data' => ['#type' => 'inline_template', '#template' => $template, '#context' => ['date' => $link, 'username' => $this->renderer()->renderPlain($username), 'message' => ['#markup' => $markup, '#allowed_tags' => Xss::getHtmlTagList()]]]]; return $column; }
/** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, $node = NULL) { $account = $this->currentUser; $langcode = $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId(); $langname = $this->languageManager->getLanguageName($langcode); $languages = $node->getTranslationLanguages(); $has_translations = count($languages) > 1; $node_storage = $this->entityManager->getStorage('node'); $type = $node->getType(); $vids = array_reverse($node_storage->revisionIds($node)); $revision_count = count($vids); $build['#title'] = $has_translations ? $this->t('@langname revisions for %title', ['@langname' => $langname, '%title' => $node->label()]) : $this->t('Revisions for %title', ['%title' => $node->label()]); $build['nid'] = array('#type' => 'hidden', '#value' => $node->id()); $table_header = array('revision' => $this->t('Revision'), 'operations' => $this->t('Operations')); // Allow comparisons only if there are 2 or more revisions. if ($revision_count > 1) { $table_header += array('select_column_one' => '', 'select_column_two' => ''); } $rev_revert_perm = $account->hasPermission("revert {$type} revisions") || $account->hasPermission('revert all revisions') || $account->hasPermission('administer nodes'); $rev_delete_perm = $account->hasPermission("delete {$type} revisions") || $account->hasPermission('delete all revisions') || $account->hasPermission('administer nodes'); $revert_permission = $rev_revert_perm && $node->access('update'); $delete_permission = $rev_delete_perm && $node->access('delete'); // Contains the table listing the revisions. $build['node_revisions_table'] = array('#type' => 'table', '#header' => $table_header, '#attributes' => array('class' => array('diff-revisions'))); $build['node_revisions_table']['#attached']['library'][] = 'diff/diff.general'; $build['node_revisions_table']['#attached']['drupalSettings']['diffRevisionRadios'] = $this->config->get('general_settings.radio_behavior'); $latest_revision = TRUE; // Add rows to the table. foreach ($vids as $vid) { if ($revision = $node_storage->loadRevision($vid)) { if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)->isRevisionTranslationAffected()) { $username = array('#theme' => 'username', '#account' => $revision->getRevisionAuthor()); $revision_date = $this->date->format($revision->getRevisionCreationTime(), 'short'); // Use revision link to link to revisions that are not active. if ($vid != $node->getRevisionId()) { $link = $this->l($revision_date, new Url('entity.node.revision', ['node' => $node->id(), 'node_revision' => $vid])); } else { $link = $node->link($revision_date); } // Default revision. if ($latest_revision) { $row = array('revision' => array('#type' => 'inline_template', '#template' => '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}', '#context' => ['date' => $link, 'username' => $this->renderer->renderPlain($username), 'message' => ['#markup' => $revision->revision_log->value, '#allowed_tags' => Xss::getHtmlTagList()]])); // Allow comparisons only if there are 2 or more revisions. if ($revision_count > 1) { $row += array('select_column_one' => array('#type' => 'radio', '#title_display' => 'invisible', '#name' => 'radios_left', '#return_value' => $vid, '#default_value' => FALSE), 'select_column_two' => array('#type' => 'radio', '#title_display' => 'invisible', '#name' => 'radios_right', '#default_value' => $vid, '#return_value' => $vid)); } $row['operations'] = array('#prefix' => '<em>', '#markup' => $this->t('Current revision'), '#suffix' => '</em>', '#attributes' => array('class' => array('revision-current'))); $latest_revision = FALSE; } else { $route_params = array('node' => $node->id(), 'node_revision' => $vid, 'langcode' => $langcode); $links = array(); if ($revert_permission) { $links['revert'] = ['title' => $this->t('Revert'), 'url' => $has_translations ? Url::fromRoute('node.revision_revert_translation_confirm', ['node' => $node->id(), 'node_revision' => $vid, 'langcode' => $langcode]) : Url::fromRoute('node.revision_revert_confirm', ['node' => $node->id(), 'node_revision' => $vid])]; } if ($delete_permission) { $links['delete'] = array('title' => $this->t('Delete'), 'url' => Url::fromRoute('node.revision_delete_confirm', $route_params)); } // Here we don't have to deal with 'only one revision' case because // if there's only one revision it will also be the default one, // entering on the first branch of this if else statement. $row = array('revision' => array('#type' => 'inline_template', '#template' => '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}', '#context' => ['date' => $link, 'username' => $this->renderer->renderPlain($username), 'message' => ['#markup' => $revision->revision_log->value, '#allowed_tags' => Xss::getHtmlTagList()]]), 'select_column_one' => array('#type' => 'radio', '#title_display' => 'invisible', '#name' => 'radios_left', '#return_value' => $vid, '#default_value' => isset($vids[1]) ? $vids[1] : FALSE), 'select_column_two' => array('#type' => 'radio', '#title_display' => 'invisible', '#name' => 'radios_right', '#return_value' => $vid, '#default_value' => FALSE), 'operations' => array('#type' => 'operations', '#links' => $links)); } // Add the row to the table. $build['node_revisions_table'][] = $row; } } } // Allow comparisons only if there are 2 or more revisions. if ($revision_count > 1) { $build['submit'] = array('#type' => 'submit', '#value' => t('Compare'), '#attributes' => array('class' => array('diff-button'))); } return $build; }