I had the need recently to embed nodes at given point in a view in Drupal 8. Could be used for adverts but in this case I had a settings form which had entity reference auto complete field which referenced some content I want to promot on homepage within the view. First thing is to build a preprocess view function.
function MYMODULE_theme_preprocess_views_view_unformatted(array &$variables) {
// Homepage view, first page insert promoted nodes.
if ($variables['view']->id() == 'homepage' &&
$variables['view']->current_display == 'page_1' &&
$variables['view']->getCurrentPage() == 0) {
$promoted = \Drupal::state()->get('homepage_hero_settings.homepage_promoted_content_items');
$structure = [
['index' => 1, 'view_mode' => 'teaser_half_overflow'],
['index' => 3, 'view_mode' => 'teaser_wide'],
['index' => 6, 'view_mode' => 'teaser_half_overflow'],
['index' => 9, 'view_mode' => 'teaser_wide'],
['index' => 10, 'view_mode' => 'teaser_half'],
['index' => 11, 'view_mode' => 'teaser_half'],
];
foreach ($promoted as $key => $promote) {
\Drupal::service('myservice')
->insertNodeIntoView($variables, $structure[$key]['index'], $promote['target_id'], $structure[$key]['view_mode']);
}
}
}
I also built a service to house the process of inserting the node into the view, see below:
/**
* Insert a node into a view at a given point.
*
* @param array $variables
* Supplied via preprocess hook.
* @param int $insert_row
* Where to insert the node in the view.
* @param int $nid
* The node id of the content to insert.
* @param string $view_mode
* How to disaply the node.
*/
public function insertNodeIntoView(array &$variables, $insert_row, $nid, $view_mode) {
$node = Node::load($nid);
$view_builder = \Drupal::entityTypeManager()->getViewBuilder('node');
$insert = [
'content' => $view_builder->view($node, $view_mode),
];
array_splice($variables['rows'], $insert_row, 0, [$insert]);
}
Thats it, took ages to figure out but this works nicely. I limited it to page 1 but if you wanted you could continue this through pagination.
Add new comment