Drupal 8 - Embed view in custom module

Drupal views are really powerful and you get a lot of functionality out of the box.

Normally you can assign a URL path in page display of the view and then access this view using that URL path. But sometimes we might want to use our own module to display or embed views through code.

To achieve this, Drupal provides us views_embed_view() helper function.

As the documentation suggests, it accepts following parameters

  • $name - Machine name of the view
  • $display_id - display id of the view. This depends on which type of display we are using. If the display is set to page, normally its display id is page_1.

This function returns a renderable array that can be rendered using Drupal\Core\Render\Renderer

Drupal renderer

Suppose you want to use your custom controller action to render a view. To achieve this, first, we need to inject Drupal\Core\Render\Renderer in our controller when creating its new instance.

namespace Drupal\music\Controller;

use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Render\Renderer;

class AlbumController extends ControllerBase {

  /**
   * @var Renderer
   */
  protected $renderer;

  public function __construct(Renderer $renderer) {
    $this->renderer = $renderer;
  }

  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('renderer')
    );
  }

}

And then in any action of this controller we can render a view like following:

public function albumSongList() {
  $content = [];
  // get renderable array for view
  $view = views_embed_view('album_song_list', 'page_1');
  // render view
  $content['#markup'] = $this->renderer->render($view);

  return $view;
}

View parameters

Sometimes our view relies on some parameters. For example, our view might display results based on some node id contextual filter. We can pass these parameters using views_embed_view as well, like following

$view = views_embed_view('album_song_list', 'page_1', $param1, $param2, ...);

After first two arguments, all arguments are passed to view as it is.

So for example, if my view requires node id to display the results properly, my action might look something like following.

public function albumSongList($node) {
  $content = [];
  // get renderable array for view
  $view = views_embed_view('album_song_list', 'page_1', $node);
  // render view
  $content['#markup'] = $this->renderer->render($view);
  // return rendered view
  return $view;
}

  PHP, Drupal 8