Issue #1026616 by fgm, Berdir, Dave Reid, fago: Implement an entity render controller.
parent
b149df70af
commit
e9ca778b53
|
@ -27,6 +27,8 @@
|
|||
* The class has to implement the
|
||||
* Drupal\Core\Entity\EntityStorageControllerInterface interface. Leave blank
|
||||
* to use the Drupal\Core\Entity\DatabaseStorageController implementation.
|
||||
* - render controller class: The name of the class that is used to render
|
||||
* the entities. Deafaults to Drupal\Core\Entity\EntityRenderController.
|
||||
* - form controller class: An associative array where the keys are the names
|
||||
* of the different form operations (such as creation, editing or deletion)
|
||||
* and the values are the names of the controller classes. To facilitate
|
||||
|
|
|
@ -49,6 +49,7 @@ function entity_get_info($entity_type = NULL) {
|
|||
'entity class' => 'Drupal\Core\Entity\Entity',
|
||||
'controller class' => 'Drupal\Core\Entity\DatabaseStorageController',
|
||||
'list controller class' => 'Drupal\Core\Entity\EntityListController',
|
||||
'render controller class' => 'Drupal\Core\Entity\EntityRenderController',
|
||||
'form controller class' => array(
|
||||
'default' => 'Drupal\Core\Entity\EntityFormController',
|
||||
),
|
||||
|
@ -316,47 +317,6 @@ function entity_get_controller($entity_type) {
|
|||
return $controllers[$entity_type];
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes hook_entity_prepare_view().
|
||||
*
|
||||
* If adding a new entity similar to nodes, comments or users, you should
|
||||
* invoke this function during the ENTITY_build_content() or
|
||||
* ENTITY_view_multiple() phases of rendering to allow other modules to alter
|
||||
* the objects during this phase. This is needed for situations where
|
||||
* information needs to be loaded outside of ENTITY_load() - particularly
|
||||
* when loading entities into one another - i.e. a user object into a node, due
|
||||
* to the potential for unwanted side-effects such as caching and infinite
|
||||
* recursion. By convention, entity_prepare_view() is called after
|
||||
* field_attach_prepare_view() to allow entity level hooks to act on content
|
||||
* loaded by field API.
|
||||
*
|
||||
* @param $entity_type
|
||||
* The type of entity, i.e. 'node', 'user'.
|
||||
* @param $entities
|
||||
* The entity objects which are being prepared for view, keyed by object ID.
|
||||
*
|
||||
* @see hook_entity_prepare_view()
|
||||
*/
|
||||
function entity_prepare_view($entity_type, $entities) {
|
||||
// To ensure hooks are only run once per entity, check for an
|
||||
// entity_view_prepared flag and only process items without it.
|
||||
// @todo: resolve this more generally for both entity and field level hooks.
|
||||
$prepare = array();
|
||||
foreach ($entities as $id => $entity) {
|
||||
if (empty($entity->entity_view_prepared)) {
|
||||
// Add this entity to the items to be prepared.
|
||||
$prepare[$id] = $entity;
|
||||
|
||||
// Mark this item as prepared.
|
||||
$entity->entity_view_prepared = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($prepare)) {
|
||||
module_invoke_all('entity_prepare_view', $prepare, $entity_type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the label of an entity.
|
||||
*
|
||||
|
@ -562,3 +522,57 @@ function entity_list_controller($entity_type) {
|
|||
$class = $entity_info['list controller class'];
|
||||
return new $class($entity_type, $storage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an entity render controller for a given entity type.
|
||||
*
|
||||
* @param string $entity_type
|
||||
* The type of the entity.
|
||||
*
|
||||
* @return Drupal\Core\Entity\EntityRenderControllerInterface
|
||||
* An entity render controller.
|
||||
*
|
||||
* @see hook_entity_info()
|
||||
*/
|
||||
function entity_render_controller($entity_type) {
|
||||
$info = entity_get_info($entity_type);
|
||||
$class = $info['render controller class'];
|
||||
return new $class($entity_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the render array for an entity.
|
||||
*
|
||||
* @param Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity to be rendered.
|
||||
* @param string $view_mode
|
||||
* The view mode that should be used to display the entity.
|
||||
* @param string $langcode
|
||||
* (optional) For which language the entity should be rendered, defaults to
|
||||
* the current content language.
|
||||
*
|
||||
* @return array
|
||||
* A render array for the entity.
|
||||
*/
|
||||
function entity_view(EntityInterface $entity, $view_mode, $langcode = NULL) {
|
||||
return entity_render_controller($entity->entityType())->view($entity, $view_mode, $langcode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the render array for the provided entities.
|
||||
*
|
||||
* @param array $entities
|
||||
* The entities to be rendered, must be of the same type.
|
||||
* @param string $view_mode
|
||||
* The view mode that should be used to display the entity.
|
||||
* @param string $langcode
|
||||
* (optional) For which language the entity should be rendered, defaults to
|
||||
* the current content language.
|
||||
*
|
||||
* @return array
|
||||
* A render array for the entities, indexed by the same keys as the
|
||||
* entities array passed in $entities.
|
||||
*/
|
||||
function entity_view_multiple(array $entities, $view_mode, $langcode = NULL) {
|
||||
return entity_render_controller(reset($entities)->entityType())->viewMultiple($entities, $view_mode, $langcode);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\Core\Entity\EntityRenderController.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Entity;
|
||||
|
||||
/**
|
||||
* Base class for entity view controllers.
|
||||
*/
|
||||
class EntityRenderController implements EntityRenderControllerInterface {
|
||||
|
||||
/**
|
||||
* The type of entities for which this controller is instantiated.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $entityType;
|
||||
|
||||
public function __construct($entity_type) {
|
||||
$this->entityType = $entity_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Drupal\Core\Entity\EntityRenderControllerInterface::buildContent().
|
||||
*/
|
||||
public function buildContent(array $entities = array(), $view_mode = 'full', $langcode = NULL) {
|
||||
// Allow modules to change the view mode.
|
||||
$context = array('langcode' => $langcode);
|
||||
|
||||
$prepare = array();
|
||||
foreach ($entities as $key => $entity) {
|
||||
// Remove previously built content, if exists.
|
||||
$entity->content = array();
|
||||
|
||||
drupal_alter('entity_view_mode', $view_mode, $entity, $context);
|
||||
$entity->content['#view_mode'] = $view_mode;
|
||||
$prepare[$view_mode][$key] = $entity;
|
||||
}
|
||||
|
||||
// Prepare and build field content, grouped by view mode.
|
||||
foreach ($prepare as $view_mode => $prepare_entities) {
|
||||
$call = array();
|
||||
// To ensure hooks are only run once per entity, check for an
|
||||
// entity_view_prepared flag and only process items without it.
|
||||
foreach ($prepare_entities as $entity) {
|
||||
if (empty($entity->entity_view_prepared)) {
|
||||
// Add this entity to the items to be prepared.
|
||||
$call[$entity->id()] = $entity;
|
||||
|
||||
// Mark this item as prepared.
|
||||
$entity->entity_view_prepared = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($call)) {
|
||||
field_attach_prepare_view($this->entityType, $call, $view_mode, $langcode);
|
||||
module_invoke_all('entity_prepare_view', $call, $this->entityType);
|
||||
}
|
||||
foreach ($entities as $entity) {
|
||||
$entity->content += field_attach_view($this->entityType, $entity, $view_mode, $langcode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides entity-specific defaults to the build process.
|
||||
*
|
||||
* @param Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity for which the defaults should be provided.
|
||||
* @param string $view_mode
|
||||
* The view mode that should be used.
|
||||
* @param string $langcode
|
||||
* (optional) For which language the entity should be prepared, defaults to
|
||||
* the current content language.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getBuildDefaults(EntityInterface $entity, $view_mode, $langcode) {
|
||||
$return = array(
|
||||
'#theme' => $this->entityType,
|
||||
"#{$this->entityType}" => $entity,
|
||||
'#view_mode' => $view_mode,
|
||||
'#langcode' => $langcode,
|
||||
);
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specific per-entity building.
|
||||
*
|
||||
* @param array $build
|
||||
* The render array that is being created.
|
||||
* @param Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity to be prepared.
|
||||
* @param string $view_mode
|
||||
* The view mode that should be used to prepare the entity.
|
||||
* @param string $langcode
|
||||
* (optional) For which language the entity should be prepared, defaults to
|
||||
* the current content language.
|
||||
*/
|
||||
protected function alterBuild(array &$build, EntityInterface $entity, $view_mode, $langcode = NULL) { }
|
||||
|
||||
/**
|
||||
* Implements Drupal\Core\Entity\EntityRenderControllerInterface::view().
|
||||
*/
|
||||
public function view(EntityInterface $entity, $view_mode = 'full', $langcode = NULL) {
|
||||
$buildList = $this->viewMultiple(array($entity), $view_mode, $langcode);
|
||||
return $buildList[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Drupal\Core\Entity\EntityRenderControllerInterface::viewMultiple().
|
||||
*/
|
||||
public function viewMultiple(array $entities = array(), $view_mode = 'full', $langcode = NULL) {
|
||||
if (!isset($langcode)) {
|
||||
$langcode = language(LANGUAGE_TYPE_CONTENT)->langcode;
|
||||
}
|
||||
$this->buildContent($entities, $view_mode, $langcode);
|
||||
|
||||
$view_hook = "{$this->entityType}_view";
|
||||
$build = array('#sorted' => TRUE);
|
||||
$weight = 0;
|
||||
foreach ($entities as $key => $entity) {
|
||||
$entity_view_mode = isset($entity->content['#view_mode']) ? $entity->content['#view_mode'] : $view_mode;
|
||||
module_invoke_all($view_hook, $entity, $entity_view_mode, $langcode);
|
||||
module_invoke_all('entity_view', $entity, $entity_view_mode, $langcode);
|
||||
|
||||
$build[$key] = $entity->content;
|
||||
// We don't need duplicate rendering info in $entity->content.
|
||||
unset($entity->content);
|
||||
|
||||
$build[$key] += $this->getBuildDefaults($entity, $entity_view_mode, $langcode);
|
||||
$this->alterBuild($build[$key], $entity, $entity_view_mode, $langcode);
|
||||
$build[$key]['#weight'] = $weight++;
|
||||
|
||||
// Allow modules to modify the structured entity.
|
||||
drupal_alter(array($view_hook, 'entity_view'), $build[$key], $entity);
|
||||
}
|
||||
|
||||
return $build;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\Core\Entity\EntityRenderControllerInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Entity;
|
||||
|
||||
/**
|
||||
* Defines a common interface for entity view controller classes.
|
||||
*/
|
||||
interface EntityRenderControllerInterface {
|
||||
/**
|
||||
* Build the structured $content property on the entity.
|
||||
*
|
||||
* @param array $entities
|
||||
* The entities, implementing EntityInterface, whose content is being built.
|
||||
* @param string $view_mode
|
||||
* (optional) The view mode that should be used to build the entity.
|
||||
* @param string $langcode
|
||||
* (optional) For which language the entity should be build, defaults to
|
||||
* the current content language.
|
||||
*
|
||||
* @return array
|
||||
* The content array.
|
||||
*/
|
||||
public function buildContent(array $entities = array(), $view_mode = 'full', $langcode = NULL);
|
||||
|
||||
/**
|
||||
* Returns the render array for the provided entity.
|
||||
*
|
||||
* @param Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity to render.
|
||||
* @param string $view_mode
|
||||
* (optional) The view mode that should be used to render the entity.
|
||||
* @param string $langcode
|
||||
* (optional) For which language the entity should be rendered, defaults to
|
||||
* the current content language.
|
||||
*
|
||||
* @return array
|
||||
* A render array for the entity.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* Can be thrown when the set of parameters is inconsistent, like when
|
||||
* trying to view a Comment and passing a Node which is not the one the
|
||||
* comment belongs to, or not passing one, and having the comment node not
|
||||
* be available for loading.
|
||||
*/
|
||||
public function view(EntityInterface $entity, $view_mode = 'full', $langcode = NULL);
|
||||
|
||||
/**
|
||||
* Returns the render array for the provided entities.
|
||||
*
|
||||
* @param array $entities
|
||||
* An array of entities implementing EntityInterface to view.
|
||||
* @param string $view_mode
|
||||
* (optional) The view mode that should be used to render the entity.
|
||||
* @param string $langcode
|
||||
* (optional) For which language the entity should be rendered, defaults to
|
||||
* the current content language.
|
||||
*
|
||||
* @return
|
||||
* A render array for the entities, indexed by the same keys as the
|
||||
* entities array passed in $entities.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* Can be thrown when the set of parameters is inconsistent, like when
|
||||
* trying to view Comments and passing a Node which is not the one the
|
||||
* comments belongs to, or not passing one, and having the comments node not
|
||||
* be available for loading.
|
||||
*/
|
||||
public function viewMultiple(array $entities = array(), $view_mode = 'full', $langcode = NULL);
|
||||
}
|
|
@ -119,6 +119,7 @@ function comment_entity_info() {
|
|||
'uuid' => 'uuid',
|
||||
),
|
||||
'bundles' => array(),
|
||||
'render controller class' => 'Drupal\comment\CommentRenderController',
|
||||
'view modes' => array(
|
||||
'full' => array(
|
||||
'label' => t('Full comment'),
|
||||
|
@ -768,7 +769,7 @@ function comment_node_page_additions(Node $node) {
|
|||
if ($cids = comment_get_thread($node, $mode, $comments_per_page)) {
|
||||
$comments = comment_load_multiple($cids);
|
||||
comment_prepare_thread($comments);
|
||||
$build = comment_view_multiple($comments, $node);
|
||||
$build = comment_view_multiple($comments);
|
||||
$build['pager']['#theme'] = 'pager';
|
||||
$additions['comments'] = $build;
|
||||
}
|
||||
|
@ -968,8 +969,6 @@ function comment_prepare_thread(&$comments) {
|
|||
*
|
||||
* @param Drupal\comment\Comment $comment
|
||||
* The comment object.
|
||||
* @param Drupal\node\Node $node
|
||||
* The node the comment is attached to.
|
||||
* @param $view_mode
|
||||
* View mode, e.g. 'full', 'teaser'...
|
||||
* @param $langcode
|
||||
|
@ -979,105 +978,8 @@ function comment_prepare_thread(&$comments) {
|
|||
* @return
|
||||
* An array as expected by drupal_render().
|
||||
*/
|
||||
function comment_view(Comment $comment, Node $node, $view_mode = 'full', $langcode = NULL) {
|
||||
if (!isset($langcode)) {
|
||||
$langcode = language(LANGUAGE_TYPE_CONTENT)->langcode;
|
||||
}
|
||||
|
||||
// Populate $comment->content with a render() array.
|
||||
comment_build_content($comment, $node, $view_mode, $langcode);
|
||||
|
||||
$build = $comment->content;
|
||||
// We don't need duplicate rendering info in comment->content.
|
||||
unset($comment->content);
|
||||
|
||||
$build += array(
|
||||
'#theme' => 'comment__node_' . $node->type,
|
||||
'#comment' => $comment,
|
||||
'#node' => $node,
|
||||
'#view_mode' => $view_mode,
|
||||
'#language' => $langcode,
|
||||
);
|
||||
|
||||
if (empty($comment->in_preview)) {
|
||||
$prefix = '';
|
||||
$is_threaded = isset($comment->divs) && variable_get('comment_default_mode_' . $node->type, COMMENT_MODE_THREADED) == COMMENT_MODE_THREADED;
|
||||
|
||||
// Add 'new' anchor if needed.
|
||||
if (!empty($comment->first_new)) {
|
||||
$prefix .= "<a id=\"new\"></a>\n";
|
||||
}
|
||||
|
||||
// Add indentation div or close open divs as needed.
|
||||
if ($is_threaded) {
|
||||
$prefix .= $comment->divs <= 0 ? str_repeat('</div>', abs($comment->divs)) : "\n" . '<div class="indented">';
|
||||
}
|
||||
|
||||
// Add anchor for each comment.
|
||||
$prefix .= "<a id=\"comment-$comment->cid\"></a>\n";
|
||||
$build['#prefix'] = $prefix;
|
||||
|
||||
// Close all open divs.
|
||||
if ($is_threaded && !empty($comment->divs_final)) {
|
||||
$build['#suffix'] = str_repeat('</div>', $comment->divs_final);
|
||||
}
|
||||
}
|
||||
|
||||
// Allow modules to modify the structured comment.
|
||||
drupal_alter(array('comment_view', 'entity_view'), $build, $comment);
|
||||
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a structured array representing the comment's content.
|
||||
*
|
||||
* The content built for the comment (field values, comments, file attachments
|
||||
* or other comment components) will vary depending on the $view_mode parameter.
|
||||
*
|
||||
* @param Drupal\comment\Comment $comment
|
||||
* A comment object.
|
||||
* @param Drupal\node\Node $node
|
||||
* The node the comment is attached to.
|
||||
* @param $view_mode
|
||||
* View mode, e.g. 'full', 'teaser'...
|
||||
* @param $langcode
|
||||
* (optional) A language code to use for rendering. Defaults to the global
|
||||
* content language of the current request.
|
||||
*/
|
||||
function comment_build_content(Comment $comment, Node $node, $view_mode = 'full', $langcode = NULL) {
|
||||
if (!isset($langcode)) {
|
||||
$langcode = language(LANGUAGE_TYPE_CONTENT)->langcode;
|
||||
}
|
||||
|
||||
// Remove previously built content, if exists.
|
||||
$comment->content = array();
|
||||
|
||||
// Allow modules to change the view mode.
|
||||
$context = array('langcode' => $langcode);
|
||||
drupal_alter('entity_view_mode', $view_mode, $comment, $context);
|
||||
|
||||
// Build fields content.
|
||||
field_attach_prepare_view('comment', array($comment->cid => $comment), $view_mode, $langcode);
|
||||
entity_prepare_view('comment', array($comment->cid => $comment), $langcode);
|
||||
$comment->content += field_attach_view('comment', $comment, $view_mode, $langcode);
|
||||
|
||||
$comment->content['links'] = array(
|
||||
'#theme' => 'links__comment',
|
||||
'#pre_render' => array('drupal_pre_render_links'),
|
||||
'#attributes' => array('class' => array('links', 'inline')),
|
||||
);
|
||||
if (empty($comment->in_preview)) {
|
||||
$comment->content['links']['comment'] = array(
|
||||
'#theme' => 'links__comment__comment',
|
||||
'#links' => comment_links($comment, $node),
|
||||
'#attributes' => array('class' => array('links', 'inline')),
|
||||
);
|
||||
}
|
||||
|
||||
// Allow modules to make their own additions to the comment.
|
||||
module_invoke_all('comment_view', $comment, $view_mode, $langcode);
|
||||
module_invoke_all('entity_view', $comment, $view_mode, $langcode);
|
||||
function comment_view(Comment $comment, $view_mode = 'full', $langcode = NULL) {
|
||||
return entity_view($comment, $view_mode, $langcode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1146,12 +1048,8 @@ function comment_links(Comment $comment, Node $node) {
|
|||
*
|
||||
* @param $comments
|
||||
* An array of comments as returned by comment_load_multiple().
|
||||
* @param Drupal\node\Node $node
|
||||
* The node the comments are attached to.
|
||||
* @param $view_mode
|
||||
* View mode, e.g. 'full', 'teaser'...
|
||||
* @param $weight
|
||||
* An integer representing the weight of the first comment in the list.
|
||||
* @param $langcode
|
||||
* A string indicating the language field values are to be shown in. If no
|
||||
* language is provided the current content language is used.
|
||||
|
@ -1161,19 +1059,8 @@ function comment_links(Comment $comment, Node $node) {
|
|||
*
|
||||
* @see drupal_render()
|
||||
*/
|
||||
function comment_view_multiple($comments, Node $node, $view_mode = 'full', $weight = 0, $langcode = NULL) {
|
||||
field_attach_prepare_view('comment', $comments, $view_mode, $langcode);
|
||||
entity_prepare_view('comment', $comments, $langcode);
|
||||
|
||||
$build = array(
|
||||
'#sorted' => TRUE,
|
||||
);
|
||||
foreach ($comments as $comment) {
|
||||
$build[$comment->cid] = comment_view($comment, $node, $view_mode, $langcode);
|
||||
$build[$comment->cid]['#weight'] = $weight;
|
||||
$weight++;
|
||||
}
|
||||
return $build;
|
||||
function comment_view_multiple($comments, $view_mode = 'full', $langcode = NULL) {
|
||||
return entity_view_multiple($comments, $view_mode, $langcode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1411,7 +1298,7 @@ function comment_node_update_index(Node $node, $langcode) {
|
|||
if ($node->comment && $cids = comment_get_thread($node, $mode, $comments_per_page)) {
|
||||
$comments = comment_load_multiple($cids);
|
||||
comment_prepare_thread($comments);
|
||||
$build = comment_view_multiple($comments, $node, $langcode);
|
||||
$build = comment_view_multiple($comments, $langcode);
|
||||
return drupal_render($build);
|
||||
}
|
||||
}
|
||||
|
@ -1639,7 +1526,7 @@ function comment_get_display_ordinal($cid, $node_type) {
|
|||
else {
|
||||
// For threaded comments, the c.thread column is used for ordering. We can
|
||||
// use the sorting code for comparison, but must remove the trailing slash.
|
||||
// See comment_view_multiple().
|
||||
// See CommentRenderController.
|
||||
$query->where('SUBSTRING(c1.thread, 1, (LENGTH(c1.thread) -1)) < SUBSTRING(c2.thread, 1, (LENGTH(c2.thread) -1))');
|
||||
}
|
||||
|
||||
|
@ -1687,7 +1574,6 @@ function comment_edit_page(Comment $comment) {
|
|||
function comment_preview(Comment $comment) {
|
||||
global $user;
|
||||
$preview_build = array();
|
||||
$node = node_load($comment->nid);
|
||||
|
||||
if (!form_get_errors()) {
|
||||
$comment_body = field_get_items('comment', $comment, 'comment_body');
|
||||
|
@ -1714,7 +1600,7 @@ function comment_preview(Comment $comment) {
|
|||
$comment->created = !empty($comment->created) ? $comment->created : REQUEST_TIME;
|
||||
$comment->changed = REQUEST_TIME;
|
||||
$comment->in_preview = TRUE;
|
||||
$comment_build = comment_view($comment, $node);
|
||||
$comment_build = comment_view($comment);
|
||||
$comment_build['#weight'] = -100;
|
||||
|
||||
$preview_build['comment_preview'] = $comment_build;
|
||||
|
@ -1724,11 +1610,11 @@ function comment_preview(Comment $comment) {
|
|||
$build = array();
|
||||
$comment = comment_load($comment->pid);
|
||||
if ($comment && $comment->status == COMMENT_PUBLISHED) {
|
||||
$build = comment_view($comment, $node);
|
||||
$build = comment_view($comment);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$build = node_view($node);
|
||||
$build = node_view(node_load($comment->nid));
|
||||
}
|
||||
|
||||
$preview_build['comment_output_below'] = $build;
|
||||
|
|
|
@ -68,7 +68,7 @@ function comment_reply(Node $node, $pid = NULL) {
|
|||
$comment->node_type = 'comment_node_' . $node->type;
|
||||
field_attach_load('comment', array($comment->cid => $comment));
|
||||
$comment->name = $comment->uid ? $comment->registered_name : $comment->name;
|
||||
$build['comment_parent'] = comment_view($comment, $node);
|
||||
$build['comment_parent'] = comment_view($comment);
|
||||
}
|
||||
else {
|
||||
drupal_set_message(t('The comment you are replying to does not exist.'), 'error');
|
||||
|
|
|
@ -36,6 +36,11 @@ class Comment extends Entity implements ContentEntityInterface {
|
|||
*/
|
||||
public $pid;
|
||||
|
||||
/**
|
||||
* The ID of the node to which the comment is attached.
|
||||
*/
|
||||
public $nid;
|
||||
|
||||
/**
|
||||
* The comment language code.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\comment\CommentRenderController.
|
||||
*/
|
||||
|
||||
namespace Drupal\comment;
|
||||
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityRenderController;
|
||||
|
||||
/**
|
||||
* Render controller for comments.
|
||||
*/
|
||||
class CommentRenderController extends EntityRenderController {
|
||||
|
||||
/**
|
||||
* Overrides Drupal\Core\Entity\EntityRenderController::buildContent().
|
||||
*
|
||||
* In addition to modifying the content key on entities, this implementation
|
||||
* will also set the node key which all comments carry.
|
||||
*/
|
||||
public function buildContent(array $entities = array(), $view_mode = 'full', $langcode = NULL) {
|
||||
$return = array();
|
||||
if (empty($entities)) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
parent::buildContent($entities, $view_mode, $langcode);
|
||||
|
||||
foreach ($entities as $entity) {
|
||||
$node = node_load($entity->nid);
|
||||
if (!$node) {
|
||||
throw new \InvalidArgumentException(t('Invalid node for comment.'));
|
||||
}
|
||||
$entity->content['#node'] = $node;
|
||||
$entity->content['#theme'] = 'comment__node_' . $node->bundle();
|
||||
$entity->content['links'] = array(
|
||||
'#theme' => 'links__comment',
|
||||
'#pre_render' => array('drupal_pre_render_links'),
|
||||
'#attributes' => array('class' => array('links', 'inline')),
|
||||
);
|
||||
if (empty($entity->in_preview)) {
|
||||
$entity->content['links'][$this->entityType] = array(
|
||||
'#theme' => 'links__comment__comment',
|
||||
// The "node" property is specified to be present, so no need to check.
|
||||
'#links' => comment_links($entity, $node),
|
||||
'#attributes' => array('class' => array('links', 'inline')),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\Core\Entity\EntityRenderController::alterBuild().
|
||||
*/
|
||||
protected function alterBuild(array &$build, EntityInterface $comment, $view_mode, $langcode = NULL) {
|
||||
parent::alterBuild($build, $comment, $view_mode, $langcode);
|
||||
if (empty($comment->in_preview)) {
|
||||
$prefix = '';
|
||||
$is_threaded = isset($comment->divs)
|
||||
&& variable_get('comment_default_mode_' . $comment->bundle(), COMMENT_MODE_THREADED) == COMMENT_MODE_THREADED;
|
||||
|
||||
// Add 'new' anchor if needed.
|
||||
if (!empty($comment->first_new)) {
|
||||
$prefix .= "<a id=\"new\"></a>\n";
|
||||
}
|
||||
|
||||
// Add indentation div or close open divs as needed.
|
||||
if ($is_threaded) {
|
||||
$prefix .= $comment->divs <= 0 ? str_repeat('</div>', abs($comment->divs)) : "\n" . '<div class="indented">';
|
||||
}
|
||||
|
||||
// Add anchor for each comment.
|
||||
$prefix .= "<a id=\"comment-$comment->cid\"></a>\n";
|
||||
$build['#prefix'] = $prefix;
|
||||
|
||||
// Close all open divs.
|
||||
if ($is_threaded && !empty($comment->divs_final)) {
|
||||
$build['#suffix'] = str_repeat('</div>', $comment->divs_final);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -39,7 +39,7 @@ class CommentContentRebuildTest extends CommentTestBase {
|
|||
|
||||
// Add the property to the content array and then see if it still exists on build.
|
||||
$comment_loaded->content['test_property'] = array('#value' => $this->randomString());
|
||||
$built_content = comment_view($comment_loaded, $this->node);
|
||||
$built_content = comment_view($comment_loaded);
|
||||
|
||||
// This means that the content was rebuilt as the added test property no longer exists.
|
||||
$this->assertFalse(isset($built_content['test_property']), 'Comment content was emptied before being built.');
|
||||
|
|
|
@ -304,7 +304,6 @@ function field_language($entity_type, $entity, $field_name = NULL, $langcode = N
|
|||
$id = $entity->id();
|
||||
$bundle = $entity->bundle();
|
||||
$langcode = field_valid_language($langcode, FALSE);
|
||||
|
||||
if (!isset($display_langcodes[$entity_type][$id][$langcode])) {
|
||||
$display_langcode = array();
|
||||
|
||||
|
|
|
@ -100,6 +100,12 @@ function file_entity_info() {
|
|||
'label' => 'filename',
|
||||
'uuid' => 'uuid',
|
||||
),
|
||||
'view modes' => array(
|
||||
'full' => array(
|
||||
'label' => t('File default'),
|
||||
'custom settings' => FALSE,
|
||||
),
|
||||
),
|
||||
'static cache' => FALSE,
|
||||
),
|
||||
);
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\node\NodeRenderController.
|
||||
*/
|
||||
|
||||
namespace Drupal\node;
|
||||
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityRenderController;
|
||||
|
||||
/**
|
||||
* Render controller for nodes.
|
||||
*/
|
||||
class NodeRenderController extends EntityRenderController {
|
||||
|
||||
/**
|
||||
* Overrides Drupal\Core\Entity\EntityRenderController::buildContent().
|
||||
*/
|
||||
public function buildContent(array $entities = array(), $view_mode = 'full', $langcode = NULL) {
|
||||
$return = array();
|
||||
if (empty($entities)) {
|
||||
return $return;
|
||||
}
|
||||
parent::buildContent($entities, $view_mode, $langcode);
|
||||
|
||||
foreach ($entities as $key => $entity) {
|
||||
$entity_view_mode = $entity->content['#view_mode'];
|
||||
|
||||
// The 'view' hook can be implemented to overwrite the default function
|
||||
// to display nodes.
|
||||
if (node_hook($entity->bundle(), 'view')) {
|
||||
$entity = node_invoke($entity, 'view', $entity_view_mode, $langcode);
|
||||
}
|
||||
|
||||
$entity->content['links'] = array(
|
||||
'#theme' => 'links__node',
|
||||
'#pre_render' => array('drupal_pre_render_links'),
|
||||
'#attributes' => array('class' => array('links', 'inline')),
|
||||
);
|
||||
|
||||
// Always display a read more link on teasers because we have no way
|
||||
// to know when a teaser view is different than a full view.
|
||||
$links = array();
|
||||
if ($entity_view_mode == 'teaser') {
|
||||
$node_title_stripped = strip_tags($entity->label());
|
||||
$links['node-readmore'] = array(
|
||||
'title' => t('Read more<span class="element-invisible"> about @title</span>', array(
|
||||
'@title' => $node_title_stripped,
|
||||
)),
|
||||
'href' => 'node/' . $entity->nid,
|
||||
'html' => TRUE,
|
||||
'attributes' => array(
|
||||
'rel' => 'tag',
|
||||
'title' => $node_title_stripped,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
$entity->content['links']['node'] = array(
|
||||
'#theme' => 'links__node__node',
|
||||
'#links' => $links,
|
||||
'#attributes' => array('class' => array('links', 'inline')),
|
||||
);
|
||||
|
||||
// Add Language field text element to node render array.
|
||||
$entity->content['language'] = array(
|
||||
'#type' => 'item',
|
||||
'#title' => t('Language'),
|
||||
'#markup' => language_name($langcode),
|
||||
'#weight' => 0,
|
||||
'#prefix' => '<div id="field-language-display">',
|
||||
'#suffix' => '</div>'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\Core\Entity\EntityRenderController::alterBuild().
|
||||
*/
|
||||
protected function alterBuild(array &$build, EntityInterface $entity, $view_mode, $langcode = NULL) {
|
||||
parent::alterBuild($build, $entity, $view_mode, $langcode);
|
||||
// Add contextual links for this node, except when the node is already being
|
||||
// displayed on its own page. Modules may alter this behavior (for example,
|
||||
// to restrict contextual links to certain view modes) by implementing
|
||||
// hook_node_view_alter().
|
||||
if (!empty($entity->nid) && !($view_mode == 'full' && node_is_page($entity))) {
|
||||
$build['#contextual_links']['node'] = array('node', array($entity->nid));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -27,8 +27,11 @@ class NodeBuildContentTest extends NodeTestBase {
|
|||
$node = $this->drupalCreateNode();
|
||||
|
||||
// Set a property in the content array so we can test for its existence later on.
|
||||
$node->content['test_content_property'] = array('#value' => $this->randomString());
|
||||
$content = node_build_content($node);
|
||||
$node->content['test_content_property'] = array(
|
||||
'#value' => $this->randomString(),
|
||||
);
|
||||
$nodes = array($node);
|
||||
$content = entity_render_controller('node')->buildContent($nodes);
|
||||
|
||||
// If the property doesn't exist it means the node->content was rebuilt.
|
||||
$this->assertFalse(isset($content['test_content_property']), 'Node content was emptied prior to being built.');
|
||||
|
|
|
@ -217,6 +217,7 @@ function node_entity_info() {
|
|||
'bundle' => 'type',
|
||||
),
|
||||
'bundles' => array(),
|
||||
'render controller class' => 'Drupal\node\NodeRenderController',
|
||||
'view modes' => array(
|
||||
'full' => array(
|
||||
'label' => t('Full content'),
|
||||
|
@ -1160,145 +1161,6 @@ function node_revision_delete($revision_id) {
|
|||
entity_revision_delete('node', $revision_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array for rendering the given node.
|
||||
*
|
||||
* @param Drupal\node\Node $node
|
||||
* A node entity.
|
||||
* @param $view_mode
|
||||
* (optional) View mode, e.g., 'full', 'teaser'... Defaults to 'full.'
|
||||
* @param $langcode
|
||||
* (optional) A language code to use for rendering. Defaults to the global
|
||||
* content language of the current request.
|
||||
*
|
||||
* @return
|
||||
* An array as expected by drupal_render().
|
||||
*/
|
||||
function node_view(Node $node, $view_mode = 'full', $langcode = NULL) {
|
||||
if (!isset($langcode)) {
|
||||
$langcode = language(LANGUAGE_TYPE_CONTENT)->langcode;
|
||||
}
|
||||
|
||||
// Populate $node->content with a render() array.
|
||||
node_build_content($node, $view_mode, $langcode);
|
||||
|
||||
$build = $node->content;
|
||||
// We don't need duplicate rendering info in node->content.
|
||||
unset($node->content);
|
||||
|
||||
$build += array(
|
||||
'#theme' => 'node',
|
||||
'#node' => $node,
|
||||
'#view_mode' => $view_mode,
|
||||
'#langcode' => $langcode,
|
||||
);
|
||||
|
||||
// Add contextual links for this node, except when the node is already being
|
||||
// displayed on its own page. Modules may alter this behavior (for example,
|
||||
// to restrict contextual links to certain view modes) by implementing
|
||||
// hook_node_view_alter().
|
||||
if (!empty($node->nid) && !($view_mode == 'full' && node_is_page($node))) {
|
||||
$build['#contextual_links']['node'] = array('node', array($node->nid));
|
||||
}
|
||||
|
||||
// Allow modules to modify the structured node.
|
||||
drupal_alter(array('node_view', 'entity_view'), $build, $node);
|
||||
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a structured array representing the node's content.
|
||||
*
|
||||
* The content built for the node (field values, comments, file attachments or
|
||||
* other node components) will vary depending on the $view_mode parameter.
|
||||
*
|
||||
* Drupal core defines the following view modes for nodes, with the following
|
||||
* default use cases:
|
||||
* - full (default): node is being displayed on its own page (node/123)
|
||||
* - teaser: node is being displayed on the default home page listing, or on
|
||||
* taxonomy listing pages.
|
||||
* - rss: node displayed in an RSS feed.
|
||||
* If search.module is enabled:
|
||||
* - search_index: node is being indexed for search.
|
||||
* - search_result: node is being displayed as a search result.
|
||||
* If book.module is enabled:
|
||||
* - print: node is being displayed in print-friendly mode.
|
||||
* Contributed modules might define additional view modes, or use existing
|
||||
* view modes in additional contexts.
|
||||
*
|
||||
* @param Drupal\node\Node $node
|
||||
* A node entity.
|
||||
* @param $view_mode
|
||||
* (optional) View mode, e.g., 'full', 'teaser'... Defaults to 'full.'
|
||||
* @param $langcode
|
||||
* (optional) A language code to use for rendering. Defaults to the global
|
||||
* content language of the current request.
|
||||
*/
|
||||
function node_build_content(Node $node, $view_mode = 'full', $langcode = NULL) {
|
||||
if (!isset($langcode)) {
|
||||
$langcode = language(LANGUAGE_TYPE_CONTENT)->langcode;
|
||||
}
|
||||
|
||||
// Remove previously built content, if exists.
|
||||
$node->content = array();
|
||||
|
||||
// Allow modules to change the view mode.
|
||||
$context = array('langcode' => $langcode);
|
||||
drupal_alter('entity_view_mode', $view_mode, $node, $context);
|
||||
|
||||
// The 'view' hook can be implemented to overwrite the default function
|
||||
// to display nodes.
|
||||
if (node_hook($node->type, 'view')) {
|
||||
$node = node_invoke($node, 'view', $view_mode, $langcode);
|
||||
}
|
||||
|
||||
// Build fields content.
|
||||
// In case of a multiple view, node_view_multiple() already ran the
|
||||
// 'prepare_view' step. An internal flag prevents the operation from running
|
||||
// twice.
|
||||
field_attach_prepare_view('node', array($node->nid => $node), $view_mode, $langcode);
|
||||
entity_prepare_view('node', array($node->nid => $node), $langcode);
|
||||
$node->content += field_attach_view('node', $node, $view_mode, $langcode);
|
||||
|
||||
// Always display a read more link on teasers because we have no way
|
||||
// to know when a teaser view is different than a full view.
|
||||
$links = array();
|
||||
$node->content['links'] = array(
|
||||
'#theme' => 'links__node',
|
||||
'#pre_render' => array('drupal_pre_render_links'),
|
||||
'#attributes' => array('class' => array('links', 'inline')),
|
||||
);
|
||||
if ($view_mode == 'teaser') {
|
||||
$node_title_stripped = strip_tags($node->label());
|
||||
$links['node-readmore'] = array(
|
||||
'title' => t('Read more<span class="element-invisible"> about @title</span>', array('@title' => $node_title_stripped)),
|
||||
'href' => 'node/' . $node->nid,
|
||||
'html' => TRUE,
|
||||
'attributes' => array('rel' => 'tag', 'title' => $node_title_stripped),
|
||||
);
|
||||
}
|
||||
$node->content['links']['node'] = array(
|
||||
'#theme' => 'links__node__node',
|
||||
'#links' => $links,
|
||||
'#attributes' => array('class' => array('links', 'inline')),
|
||||
);
|
||||
|
||||
// Add Language field text element to node render array.
|
||||
$node->content['language'] = array(
|
||||
'#type' => 'item',
|
||||
'#title' => t('Language'),
|
||||
'#markup' => language_name($langcode),
|
||||
'#weight' => 0,
|
||||
'#prefix' => '<div id="field-language-display">',
|
||||
'#suffix' => '</div>'
|
||||
);
|
||||
|
||||
// Allow modules to make their own additions to the node.
|
||||
module_invoke_all('node_view', $node, $view_mode, $langcode);
|
||||
module_invoke_all('entity_view', $node, $view_mode, $langcode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Page callback: Generates an array which displays a node detail page.
|
||||
*
|
||||
|
@ -1319,7 +1181,7 @@ function node_show(Node $node, $message = FALSE) {
|
|||
}
|
||||
|
||||
// For markup consistency with other pages, use node_view_multiple() rather than node_view().
|
||||
$nodes = node_view_multiple(array($node->nid => $node), 'full');
|
||||
$nodes = array('nodes' => node_view_multiple(array($node->nid => $node), 'full'));
|
||||
|
||||
// Update the history table, stating that this user viewed this node.
|
||||
node_tag_new($node);
|
||||
|
@ -2537,6 +2399,24 @@ function node_feed($nids = FALSE, $channel = array()) {
|
|||
return new Response($output, 200, array('Content-Type' => 'application/rss+xml; charset=utf-8'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array for rendering the given node.
|
||||
*
|
||||
* @param Drupal\node\Node $node
|
||||
* A node entity.
|
||||
* @param $view_mode
|
||||
* (optional) View mode, e.g., 'full', 'teaser'... Defaults to 'full.'
|
||||
* @param $langcode
|
||||
* (optional) A language code to use for rendering. Defaults to the global
|
||||
* content language of the current request.
|
||||
*
|
||||
* @return
|
||||
* An array as expected by drupal_render().
|
||||
*/
|
||||
function node_view(Node $node, $view_mode = 'full', $langcode = NULL) {
|
||||
return entity_view($node, $view_mode, $langcode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a drupal_render() style array from an array of loaded nodes.
|
||||
*
|
||||
|
@ -2544,8 +2424,6 @@ function node_feed($nids = FALSE, $channel = array()) {
|
|||
* An array of nodes as returned by node_load_multiple().
|
||||
* @param $view_mode
|
||||
* (optional) View mode, e.g., 'full', 'teaser'... Defaults to 'teaser.'
|
||||
* @param $weight
|
||||
* (optional) Integer representing the weight of the first node in the list.
|
||||
* @param $langcode
|
||||
* (optional) A language code to use for rendering. Defaults to the global
|
||||
* content language of the current request.
|
||||
|
@ -2553,17 +2431,8 @@ function node_feed($nids = FALSE, $channel = array()) {
|
|||
* @return
|
||||
* An array in the format expected by drupal_render().
|
||||
*/
|
||||
function node_view_multiple($nodes, $view_mode = 'teaser', $weight = 0, $langcode = NULL) {
|
||||
field_attach_prepare_view('node', $nodes, $view_mode, $langcode);
|
||||
entity_prepare_view('node', $nodes, $langcode);
|
||||
$build = array();
|
||||
foreach ($nodes as $node) {
|
||||
$build['nodes'][$node->nid] = node_view($node, $view_mode, $langcode);
|
||||
$build['nodes'][$node->nid]['#weight'] = $weight;
|
||||
$weight++;
|
||||
}
|
||||
$build['nodes']['#sorted'] = TRUE;
|
||||
return $build;
|
||||
function node_view_multiple($nodes, $view_mode = 'teaser', $langcode = NULL) {
|
||||
return entity_view_multiple($nodes, $view_mode, $langcode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2590,7 +2459,7 @@ function node_page_default() {
|
|||
|
||||
if (!empty($nids)) {
|
||||
$nodes = node_load_multiple($nids);
|
||||
$build = node_view_multiple($nodes);
|
||||
$build['nodes'] = node_view_multiple($nodes);
|
||||
|
||||
// 'rss.xml' is a path, not a file, registered in node_menu().
|
||||
drupal_add_feed('rss.xml', $site_config->get('name') . ' ' . t('RSS'));
|
||||
|
|
|
@ -121,7 +121,9 @@ class SearchMultilingualEntityTest extends SearchTestBase {
|
|||
$body_language_variant = end($node->body);
|
||||
$search_result = node_search_execute($body_language_variant[0]['value']);
|
||||
// See whether we get the same node as a result.
|
||||
$this->assertEqual($search_result[0]['node']->nid, $node->nid, 'The search has resulted the correct node.');
|
||||
$sts = $this->assertTrue(!empty($search_result[0]['node']->nid)
|
||||
&& $search_result[0]['node']->nid == $node->nid,
|
||||
'The search has resulted the correct node.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -362,7 +362,7 @@ function hook_update_index() {
|
|||
variable_set('node_cron_last', $node->changed);
|
||||
|
||||
// Render the node.
|
||||
node_build_content($node, 'search_index');
|
||||
$build = node_view($node, 'search_index');
|
||||
$node->rendered = drupal_render($node->content);
|
||||
|
||||
$text = '<h1>' . check_plain($node->label()) . '</h1>' . $node->rendered;
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\taxonomy\TermRenderController.
|
||||
*/
|
||||
|
||||
namespace Drupal\taxonomy;
|
||||
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityRenderController;
|
||||
|
||||
/**
|
||||
* Render controller for taxonomy terms.
|
||||
*/
|
||||
class TermRenderController extends EntityRenderController {
|
||||
|
||||
/**
|
||||
* Overrides Drupal\Core\Entity\EntityRenderController::buildContent().
|
||||
*/
|
||||
public function buildContent(array $entities = array(), $view_mode = 'full', $langcode = NULL) {
|
||||
parent::buildContent($entities, $view_mode, $langcode);
|
||||
|
||||
foreach ($entities as $entity) {
|
||||
// Add the description if enabled.
|
||||
$bundle = $entity->bundle();
|
||||
$entity_view_mode = $entity->content['#view_mode'];
|
||||
$fields = field_extra_fields_get_display($this->entityType, $bundle, $entity_view_mode);
|
||||
if (!empty($entity->description) && isset($fields['description']) && $fields['description']['visible']) {
|
||||
$entity->content['description'] = array(
|
||||
'#markup' => check_markup($entity->description, $entity->format, '', TRUE),
|
||||
'#weight' => $fields['description']['weight'],
|
||||
'#prefix' => '<div class="taxonomy-term-description">',
|
||||
'#suffix' => '</div>',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function getBuildDefaults(EntityInterface $entity, $view_mode, $langcode) {
|
||||
$return = parent::getBuildDefaults($entity, $view_mode, $langcode);
|
||||
|
||||
// TODO: rename "term" to "taxonomy_term" in theme_taxonomy_term().
|
||||
$return['#term'] = $return["#{$this->entityType}"];
|
||||
unset($return["#{$this->entityType}"]);
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
protected function alterBuild(array &$build, EntityInterface $entity, $view_mode, $langcode = NULL) {
|
||||
parent::alterBuild($build, $entity, $view_mode, $langcode);
|
||||
$build['#attached']['css'][] = drupal_get_path('module', 'taxonomy') . '/taxonomy.css';
|
||||
}
|
||||
}
|
|
@ -130,6 +130,7 @@ function taxonomy_entity_info() {
|
|||
'bundle' => 'machine_name',
|
||||
),
|
||||
'bundles' => array(),
|
||||
'render controller class' => 'Drupal\taxonomy\TermRenderController',
|
||||
'view modes' => array(
|
||||
// @todo View mode for display as a field (when attached to nodes etc).
|
||||
'full' => array(
|
||||
|
@ -163,6 +164,12 @@ function taxonomy_entity_info() {
|
|||
'label' => 'name',
|
||||
),
|
||||
'fieldable' => FALSE,
|
||||
'view modes' => array(
|
||||
'full' => array(
|
||||
'label' => t('Taxonomy vocabulary default'),
|
||||
'custom settings' => FALSE,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $return;
|
||||
|
@ -574,22 +581,26 @@ function taxonomy_term_delete_multiple(array $tids) {
|
|||
*
|
||||
* @param Drupal\taxonomy\Term $term
|
||||
* A taxonomy term object.
|
||||
* @param string $view_mode
|
||||
* View mode, e.g. 'full', 'teaser'...
|
||||
* @param string $langcode
|
||||
* (optional) A language code to use for rendering. Defaults to the global
|
||||
* content language of the current request.
|
||||
*
|
||||
* @return array
|
||||
* A $page element suitable for use by drupal_page_render().
|
||||
*/
|
||||
function taxonomy_term_show(Term $term) {
|
||||
return taxonomy_term_view_multiple(array($term->tid => $term), 'full');
|
||||
function taxonomy_term_view(Term $term, $view_mode = 'full', $langcode = NULL) {
|
||||
return entity_view($term, $view_mode, $langcode);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs a drupal_render() style array from an array of loaded terms.
|
||||
*
|
||||
* @param array $terms
|
||||
* An array of taxonomy terms as returned by taxonomy_term_load_multiple().
|
||||
* @param string $view_mode
|
||||
* View mode, e.g. 'full', 'teaser'...
|
||||
* @param int $weight
|
||||
* An integer representing the weight of the first node in the list.
|
||||
* @param string $langcode
|
||||
* (optional) A language code to use for rendering. Defaults to the global
|
||||
* content language of the current request.
|
||||
|
@ -597,115 +608,8 @@ function taxonomy_term_show(Term $term) {
|
|||
* @return array
|
||||
* An array in the format expected by drupal_render().
|
||||
*/
|
||||
function taxonomy_term_view_multiple(array $terms, $view_mode = 'teaser', $weight = 0, $langcode = NULL) {
|
||||
field_attach_prepare_view('taxonomy_term', $terms, $view_mode, $langcode);
|
||||
entity_prepare_view('taxonomy_term', $terms, $langcode);
|
||||
$build = array();
|
||||
foreach ($terms as $term) {
|
||||
$build['taxonomy_terms'][$term->tid] = taxonomy_term_view($term, $view_mode, $langcode);
|
||||
$build['taxonomy_terms'][$term->tid]['#weight'] = $weight;
|
||||
$weight++;
|
||||
}
|
||||
$build['taxonomy_terms']['#sorted'] = TRUE;
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a structured array representing the term's content.
|
||||
*
|
||||
* The content built for the taxonomy term (field values, file attachments or
|
||||
* other term components) will vary depending on the $view_mode parameter.
|
||||
*
|
||||
* Drupal core defines the following view modes for terms, with the following
|
||||
* default use cases:
|
||||
* - full (default): term is displayed on its own page (taxonomy/term/123)
|
||||
* Contributed modules might define additional view modes, or use existing
|
||||
* view modes in additional contexts.
|
||||
*
|
||||
* @param Drupal\taxonomy\Term $term
|
||||
* A taxonomy term object.
|
||||
* @param string $view_mode
|
||||
* View mode, e.g. 'full', 'teaser'...
|
||||
* @param string $langcode
|
||||
* (optional) A language code to use for rendering. Defaults to the global
|
||||
* content language of the current request.
|
||||
*/
|
||||
function taxonomy_term_build_content(Term $term, $view_mode = 'full', $langcode = NULL) {
|
||||
if (!isset($langcode)) {
|
||||
$langcode = language(LANGUAGE_TYPE_CONTENT)->langcode;
|
||||
}
|
||||
|
||||
// Remove previously built content, if exists.
|
||||
$term->content = array();
|
||||
|
||||
// Allow modules to change the view mode.
|
||||
$context = array('langcode' => $langcode);
|
||||
drupal_alter('entity_view_mode', $view_mode, $term, $context);
|
||||
|
||||
// Try to add in the core taxonomy pieces like description and nodes.
|
||||
$settings = field_view_mode_settings($term->entityType(), $term->bundle());
|
||||
$fields = field_extra_fields_get_display($term->entityType(), $term->bundle(), $view_mode);
|
||||
if (!empty($term->description) && isset($fields['description']) && $fields['description']['visible']) {
|
||||
$term->content['description'] = array(
|
||||
'#markup' => check_markup($term->description, $term->format, '', TRUE),
|
||||
'#weight' => $fields['description']['weight'],
|
||||
'#prefix' => '<div class="taxonomy-term-description">',
|
||||
'#suffix' => '</div>',
|
||||
);
|
||||
}
|
||||
|
||||
// Build fields content.
|
||||
// In case of a multiple view, taxonomy_term_view_multiple() already ran the
|
||||
// 'prepare_view' step. An internal flag prevents the operation from running
|
||||
// twice.
|
||||
field_attach_prepare_view('taxonomy_term', array($term->tid => $term), $view_mode, $langcode);
|
||||
entity_prepare_view('taxonomy_term', array($term->tid => $term), $langcode);
|
||||
$term->content += field_attach_view('taxonomy_term', $term, $view_mode, $langcode);
|
||||
|
||||
// Allow modules to make their own additions to the taxonomy term.
|
||||
module_invoke_all('taxonomy_term_view', $term, $view_mode, $langcode);
|
||||
module_invoke_all('entity_view', $term, $view_mode, $langcode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an array for rendering the given term.
|
||||
*
|
||||
* @param Drupal\taxonomy\Term $term
|
||||
* A taxonomy term entity.
|
||||
* @param string $view_mode
|
||||
* View mode, e.g. 'full', 'teaser'...
|
||||
* @param string $langcode
|
||||
* (optional) A language code to use for rendering. Defaults to the global
|
||||
* content language of the current request.
|
||||
*
|
||||
* @return
|
||||
* An array as expected by drupal_render().
|
||||
*/
|
||||
function taxonomy_term_view(Term $term, $view_mode = 'full', $langcode = NULL) {
|
||||
if (!isset($langcode)) {
|
||||
$langcode = language(LANGUAGE_TYPE_CONTENT)->langcode;
|
||||
}
|
||||
|
||||
// Populate $term->content with a render() array.
|
||||
taxonomy_term_build_content($term, $view_mode, $langcode);
|
||||
$build = $term->content;
|
||||
|
||||
// We don't need duplicate rendering info in $term->content.
|
||||
unset($term->content);
|
||||
|
||||
$build += array(
|
||||
'#theme' => 'taxonomy_term',
|
||||
'#term' => $term,
|
||||
'#view_mode' => $view_mode,
|
||||
'#language' => $langcode,
|
||||
);
|
||||
|
||||
$build['#attached']['css'][] = drupal_get_path('module', 'taxonomy') . '/taxonomy.css';
|
||||
|
||||
// Allow modules to modify the structured term.
|
||||
drupal_alter(array('taxonomy_term_view', 'entity_view'), $build, $term);
|
||||
|
||||
return $build;
|
||||
function taxonomy_term_view_multiple(array $terms, $view_mode = 'full', $langcode = NULL) {
|
||||
return entity_view_multiple($terms, $view_mode, $langcode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -45,10 +45,10 @@ function taxonomy_term_page(Term $term) {
|
|||
// Set the non-aliased path as a default shortlink.
|
||||
drupal_add_html_head_link(array('rel' => 'shortlink', 'href' => url($uri['path'], array_merge($uri['options'], array('alias' => TRUE)))), TRUE);
|
||||
|
||||
$build = taxonomy_term_show($term);
|
||||
$build['taxonomy_terms'] = taxonomy_term_view_multiple(array($term->id() => $term));
|
||||
if ($nids = taxonomy_select_nodes($term->tid, TRUE, variable_get('default_nodes_main', 10))) {
|
||||
$nodes = node_load_multiple($nids);
|
||||
$build += node_view_multiple($nodes);
|
||||
$build['nodes'] = node_view_multiple($nodes);
|
||||
$build['pager'] = array(
|
||||
'#theme' => 'pager',
|
||||
'#weight' => 5,
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\user\UserRenderController.
|
||||
*/
|
||||
|
||||
namespace Drupal\user;
|
||||
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityRenderController;
|
||||
|
||||
/**
|
||||
* Render controller for users.
|
||||
*/
|
||||
class UserRenderController extends EntityRenderController {
|
||||
|
||||
/**
|
||||
* Overrides Drupal\Core\Entity\EntityRenderController::getBuildDefaults().
|
||||
*/
|
||||
protected function getBuildDefaults(EntityInterface $entity, $view_mode, $langcode) {
|
||||
$return = parent::getBuildDefaults($entity, $view_mode, $langcode);
|
||||
|
||||
// @todo rename "theme_user_profile" to "theme_user", 'account' to 'user'.
|
||||
$return['#theme'] = 'user_profile';
|
||||
$return['#account'] = $return['#user'];
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
|
@ -168,6 +168,7 @@ function user_entity_info() {
|
|||
),
|
||||
),
|
||||
),
|
||||
'render controller class' => 'Drupal\user\UserRenderController',
|
||||
'view modes' => array(
|
||||
'full' => array(
|
||||
'label' => t('User account'),
|
||||
|
@ -2062,61 +2063,25 @@ function user_view_page($account) {
|
|||
* An array as expected by drupal_render().
|
||||
*/
|
||||
function user_view($account, $view_mode = 'full', $langcode = NULL) {
|
||||
if (!isset($langcode)) {
|
||||
$langcode = language(LANGUAGE_TYPE_CONTENT)->langcode;
|
||||
}
|
||||
|
||||
// Retrieve all profile fields and attach to $account->content.
|
||||
user_build_content($account, $view_mode, $langcode);
|
||||
|
||||
$build = $account->content;
|
||||
// We don't need duplicate rendering info in account->content.
|
||||
unset($account->content);
|
||||
|
||||
$build += array(
|
||||
'#theme' => 'user_profile',
|
||||
'#account' => $account,
|
||||
'#view_mode' => $view_mode,
|
||||
'#language' => $langcode,
|
||||
);
|
||||
|
||||
// Allow modules to modify the structured user.
|
||||
drupal_alter(array('user_view', 'entity_view'), $build, $account);
|
||||
|
||||
return $build;
|
||||
return entity_view($account, $view_mode, $langcode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a structured array representing the profile content.
|
||||
* Constructs a drupal_render() style array from an array of loaded users.
|
||||
*
|
||||
* @param $account
|
||||
* A user object.
|
||||
* @param $accounts
|
||||
* An array of user accounts as returned by user_load_multiple().
|
||||
* @param $view_mode
|
||||
* View mode, e.g. 'full'.
|
||||
* (optional) View mode, e.g., 'full', 'teaser'... Defaults to 'teaser.'
|
||||
* @param $langcode
|
||||
* (optional) A language code to use for rendering. Defaults to the global
|
||||
* content language of the current request.
|
||||
*
|
||||
* @return
|
||||
* An array in the format expected by drupal_render().
|
||||
*/
|
||||
function user_build_content($account, $view_mode = 'full', $langcode = NULL) {
|
||||
if (!isset($langcode)) {
|
||||
$langcode = language(LANGUAGE_TYPE_CONTENT)->langcode;
|
||||
}
|
||||
|
||||
// Remove previously built content, if exists.
|
||||
$account->content = array();
|
||||
|
||||
// Allow modules to change the view mode.
|
||||
$context = array('langcode' => $langcode);
|
||||
drupal_alter('entity_view_mode', $view_mode, $account, $context);
|
||||
|
||||
// Build fields content.
|
||||
field_attach_prepare_view('user', array($account->uid => $account), $view_mode, $langcode);
|
||||
entity_prepare_view('user', array($account->uid => $account), $langcode);
|
||||
$account->content += field_attach_view('user', $account, $view_mode, $langcode);
|
||||
|
||||
// Populate $account->content with a render() array.
|
||||
module_invoke_all('user_view', $account, $view_mode, $langcode);
|
||||
module_invoke_all('entity_view', $account, $view_mode, $langcode);
|
||||
function user_view_multiple($accounts, $view_mode = 'full', $langcode = NULL) {
|
||||
return entity_view($accounts, $view_mode, $langcode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue