diff --git a/modules/render/eca_render.install b/modules/render/eca_render.install
new file mode 100644
index 0000000000000000000000000000000000000000..ae2716a0fc04c180b14ed871d5f1fbed7559f23b
--- /dev/null
+++ b/modules/render/eca_render.install
@@ -0,0 +1,13 @@
+<?php
+
+/**
+ * @file
+ * ECA Render install file.
+ */
+
+/**
+ * Update existing models.
+ */
+function eca_render_update_8001(): void {
+  \Drupal::service('eca.update')->updateAllModels();
+}
diff --git a/modules/render/src/Plugin/Action/Views.php b/modules/render/src/Plugin/Action/Views.php
index 3a7bd7760b5013dbff9a3eececf4d5e1b40bed70..3407e6c933e8554a9de8f5e72263410c96ff5e00 100644
--- a/modules/render/src/Plugin/Action/Views.php
+++ b/modules/render/src/Plugin/Action/Views.php
@@ -11,6 +11,7 @@ use Drupal\Core\Render\RendererInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\eca\Plugin\ECA\PluginFormTrait;
 use Drupal\views\Entity\View;
+use Drupal\views\Views as ViewsService;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -52,6 +53,7 @@ class Views extends RenderElementActionBase {
       'view_id' => '',
       'display_id' => 'default',
       'arguments' => '',
+      'items_per_page' => '',
     ] + parent::defaultConfiguration();
   }
 
@@ -80,6 +82,7 @@ class Views extends RenderElementActionBase {
       '#default_value' => $this->configuration['display_id'],
       '#weight' => -40,
       '#required' => FALSE,
+      '#eca_token_replacement' => TRUE,
     ];
     $form['arguments'] = [
       '#type' => 'textarea',
@@ -87,7 +90,17 @@ class Views extends RenderElementActionBase {
       '#default_value' => $this->configuration['arguments'],
       '#weight' => -30,
       '#required' => FALSE,
+      '#eca_token_replacement' => TRUE,
     ];
+    $form['items_per_page'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Items per page'),
+      '#default_value' => $this->configuration['items_per_page'],
+      '#weight' => -30,
+      '#required' => FALSE,
+      '#eca_token_replacement' => TRUE,
+    ];
+
     return parent::buildConfigurationForm($form, $form_state);
   }
 
@@ -99,6 +112,7 @@ class Views extends RenderElementActionBase {
     $this->configuration['view_id'] = $form_state->getValue('view_id');
     $this->configuration['display_id'] = $form_state->getValue('display_id');
     $this->configuration['arguments'] = $form_state->getValue('arguments');
+    $this->configuration['items_per_page'] = $form_state->getValue('items_per_page');
   }
 
   /**
@@ -111,7 +125,7 @@ class Views extends RenderElementActionBase {
       $view = View::load($view_id);
       if ($view && $view->status()) {
         $viewExecutable = $view->getExecutable();
-        $display_id = $this->getDisplayId();
+        $display_id = $this->getConfigValue('display_id');
         $display = NULL;
         if ($display_id !== '') {
           if ($viewExecutable->setDisplay($display_id)) {
@@ -134,14 +148,29 @@ class Views extends RenderElementActionBase {
    * {@inheritdoc}
    */
   protected function doBuild(array &$build): void {
-    $args = [$this->getViewId(), $this->getDisplayId()];
-    foreach (explode('/', $this->getArguments()) as $argument) {
+    $view = ViewsService::getView($this->getViewId());
+    $view->setDisplay($this->getConfigValue('display_id'));
+
+    $args = [];
+    foreach (explode('/', $this->getConfigValue('arguments')) as $argument) {
       if ($argument !== '') {
         $args[] = $argument;
       }
     }
+    $view->setArguments($args);
+
+    $itemsPerPage = $this->getConfigValue('items_per_page');
+    if (!empty($itemsPerPage)) {
+      $view->setItemsPerPage((int) $itemsPerPage);
+    }
 
-    $build = views_embed_view(...$args) ?? [];
+    $view->preExecute();
+    $view->execute();
+
+    $build = $view->buildRenderable();
+    if (empty($build)) {
+      return;
+    }
 
     $markup = $this->renderer->executeInRenderContext(new RenderContext(), function () use (&$build) {
       return $this->renderer->render($build);
@@ -174,27 +203,21 @@ class Views extends RenderElementActionBase {
     if ($view_id === '_eca_token') {
       $view_id = $this->getTokenValue('view_id', '');
     }
+
     return trim((string) $view_id);
   }
 
   /**
-   * Get the configured display ID.
+   * Retrieve a configuration value.
    *
-   * @return string
-   *   The display ID.
-   */
-  protected function getDisplayId(): string {
-    return trim((string) $this->tokenService->replaceClear($this->configuration['display_id']));
-  }
-
-  /**
-   * Get the configured Views arguments.
+   * @param string $key
+   *   The configuration key.
    *
    * @return string
-   *   The arguments, multiple arguments are separated by "/".
+   *   The value of the token.
    */
-  protected function getArguments(): string {
-    return trim((string) $this->tokenService->replaceClear($this->configuration['arguments']));
+  protected function getConfigValue(string $key): string {
+    return trim((string) $this->tokenService->replaceClear($this->configuration[$key]));
   }
 
 }
diff --git a/modules/render/tests/src/Kernel/ViewsTest.php b/modules/render/tests/src/Kernel/ViewsTest.php
index 50c3a32aa77de15b06879ba69f40272060a6958e..2afde2c9c2a92a833b6498bf36aa6906edd3de93 100644
--- a/modules/render/tests/src/Kernel/ViewsTest.php
+++ b/modules/render/tests/src/Kernel/ViewsTest.php
@@ -29,6 +29,7 @@ class ViewsTest extends RenderActionsTestBase {
       'view_id' => 'test_view',
       'display_id' => 'default',
       'arguments' => '',
+      'items_per_page' => '3',
       'token_name' => '',
       'name' => '',
       'weight' => '100',
diff --git a/modules/views/src/Plugin/Action/ViewsQuery.php b/modules/views/src/Plugin/Action/ViewsQuery.php
index 67aedd4966b972972c22d8294cff34d9690d1793..70c32e0a6e2f6a320df684f6346f7cac5a3300e1 100644
--- a/modules/views/src/Plugin/Action/ViewsQuery.php
+++ b/modules/views/src/Plugin/Action/ViewsQuery.php
@@ -10,10 +10,12 @@ use Drupal\Core\TypedData\ListDataDefinition;
 use Drupal\Core\TypedData\Plugin\DataType\ItemList;
 use Drupal\eca\Plugin\Action\ConfigurableActionBase;
 use Drupal\eca\Plugin\ECA\PluginFormTrait;
+use Drupal\eca\Service\YamlParser;
 use Drupal\views\Entity\View;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
 use Drupal\views\Plugin\views\query\Sql;
 use Drupal\views\ViewExecutable;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Run views query.
@@ -21,14 +23,24 @@ use Drupal\views\ViewExecutable;
  * @Action(
  *   id = "eca_views_query",
  *   label = @Translation("Views: Execute query"),
- *   description = @Translation("Use a View to execute a query and store the results in a token that contains an indexed list of the results. Despite the type of view that you use, always get the complete entities obtained by the view. You can access the entity properties using the token style."),
- *   eca_version_introduced = "1.0.0"
+ *   description = @Translation("Use a View to execute a query and store the
+ *   results in a token that contains an indexed list of the results. Despite
+ *   the type of view that you use, always get the complete entities obtained
+ *   by the view. You can access the entity properties using the token
+ *   style."), eca_version_introduced = "1.0.0"
  * )
  */
 class ViewsQuery extends ConfigurableActionBase {
 
   use PluginFormTrait;
 
+  /**
+   * The YAML parser.
+   *
+   * @var \Drupal\eca\Service\YamlParser
+   */
+  protected YamlParser $yamlParser;
+
   /**
    * The executable view.
    *
@@ -36,6 +48,16 @@ class ViewsQuery extends ConfigurableActionBase {
    */
   protected ViewExecutable $view;
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
+    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
+    $instance->yamlParser = $container->get('eca.service.yaml_parser');
+
+    return $instance;
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -90,6 +112,7 @@ class ViewsQuery extends ConfigurableActionBase {
       'view_id' => '',
       'display_id' => 'default',
       'arguments' => '',
+      'exposed_input' => '',
     ] + parent::defaultConfiguration();
   }
 
@@ -136,6 +159,13 @@ class ViewsQuery extends ConfigurableActionBase {
       '#maxlength' => 512,
       '#weight' => -30,
     ];
+    $form['exposed_input'] = [
+      '#type' => 'textarea',
+      '#title' => $this->t('Exposed input'),
+      '#default_value' => $this->configuration['exposed_input'],
+      '#description' => $this->t('Provide the values for the exposed filters. Data should be set using YAML format, for example <em>myfilter: "My value"</em>. When using tokens and YAML altogether, make sure that tokens are wrapped as a string. Example: <em>myfilter: "[node:title]"</em>'),
+    ];
+
     return parent::buildConfigurationForm($form, $form_state);
   }
 
@@ -147,6 +177,7 @@ class ViewsQuery extends ConfigurableActionBase {
     $this->configuration['view_id'] = $form_state->getValue('view_id');
     $this->configuration['display_id'] = $form_state->getValue('display_id');
     $this->configuration['arguments'] = $form_state->getValue('arguments');
+    $this->configuration['exposed_input'] = $form_state->getValue('exposed_input');
     parent::submitConfigurationForm($form, $form_state);
   }
 
@@ -190,6 +221,7 @@ class ViewsQuery extends ConfigurableActionBase {
       }
     }
     $this->view->setArguments($args);
+    $this->view->setExposedInput($this->getExposedInput());
 
     return $this->view->getDisplay();
   }
@@ -228,6 +260,21 @@ class ViewsQuery extends ConfigurableActionBase {
     return trim((string) $this->tokenService->replaceClear($this->configuration['arguments']));
   }
 
+  /**
+   * Get the configured Views exposed input.
+   *
+   * @return array
+   *   The exposed input.
+   */
+  protected function getExposedInput(): array {
+    $exposedInput = $this->configuration['exposed_input'];
+    if (empty($exposedInput)) {
+      return [];
+    }
+
+    return (array) $this->yamlParser->parse($exposedInput);
+  }
+
   /**
    * Extracts the entities out of the executed View query.
    *
diff --git a/modules/views/src/Plugin/Action/ViewsSetPagination.php b/modules/views/src/Plugin/Action/ViewsSetPagination.php
new file mode 100644
index 0000000000000000000000000000000000000000..4d33652c5487b7a5622fce0b8abe148f07c1afaa
--- /dev/null
+++ b/modules/views/src/Plugin/Action/ViewsSetPagination.php
@@ -0,0 +1,124 @@
+<?php
+
+namespace Drupal\eca_views\Plugin\Action;
+
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\eca\Plugin\Action\ConfigurableActionBase;
+use Drupal\eca\Plugin\DataType\DataTransferObject;
+use Drupal\eca_views\Event\ViewsBase;
+use Drupal\views\Plugin\views\pager\PagerPluginBase;
+
+/**
+ * Set a views pagination values.
+ *
+ * @Action(
+ *   id = "eca_views_set_pagination_values",
+ *   label = @Translation("Views: Set pagination values"),
+ *   eca_version_introduced = "2.1.3"
+ * )
+ */
+class ViewsSetPagination extends ConfigurableActionBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration(): array {
+    return [
+      'items_per_page' => '',
+      'offset' => '',
+    ] + parent::defaultConfiguration();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
+    $form = parent::buildConfigurationForm($form, $form_state);
+
+    $form['items_per_page'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Items per page'),
+      '#default_value' => $this->configuration['items_per_page'],
+      '#weight' => -30,
+      '#eca_token_replacement' => TRUE,
+    ];
+
+    $form['offset'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Offset'),
+      '#default_value' => $this->configuration['offset'],
+      '#weight' => -20,
+      '#eca_token_replacement' => TRUE,
+    ];
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
+    parent::submitConfigurationForm($form, $form_state);
+
+    $this->configuration['items_per_page'] = $form_state->getValue('items_per_page');
+    $this->configuration['offset'] = $form_state->getValue('offset');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function execute(mixed $object = NULL): void {
+    $event = $this->getEvent();
+    if (!($event instanceof ViewsBase)) {
+      return;
+    }
+
+    $pager = $event->getView()->getPager();
+    if (!($pager instanceof PagerPluginBase)) {
+      return;
+    }
+
+    if ($value = $this->getValue('items_per_page')) {
+      $pager->setItemsPerPage($value);
+    }
+
+    if ($value = $this->getValue('offset')) {
+      $pager->setOffset($value);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function access($object, ?AccountInterface $account = NULL, $return_as_object = FALSE) {
+    $result = AccessResult::forbidden();
+    $event = $this->getEvent();
+    if ($event instanceof ViewsBase && ($event->getView()->getPager() instanceof PagerPluginBase)) {
+      $result = AccessResult::allowed();
+    }
+
+    return $return_as_object ? $result : $result->isAllowed();
+  }
+
+  /**
+   * Retrieve the value of the configuration item.
+   *
+   * @param string $key
+   *   The key of the config item.
+   *
+   * @return string
+   *   Returns the replaced token or the actual value.
+   */
+  protected function getValue(string $key): string {
+    $token = trim((string) $this->configuration[$key]);
+    $value = $this->tokenService->getOrReplace($token);
+    if ($value instanceof DataTransferObject) {
+      return $value->getValue();
+    }
+
+    return $value;
+  }
+
+}
diff --git a/src/Plugin/ECA/PluginFormTrait.php b/src/Plugin/ECA/PluginFormTrait.php
index 0836e6ba2f44eb5e3b7a5a874d01b919b8f74e93..db15de3d8d253d0f4816e93c707d03bfb8c8bc56 100644
--- a/src/Plugin/ECA/PluginFormTrait.php
+++ b/src/Plugin/ECA/PluginFormTrait.php
@@ -3,6 +3,7 @@
 namespace Drupal\eca\Plugin\ECA;
 
 use Drupal\Core\Render\Element;
+use Drupal\Core\TypedData\Plugin\DataType\StringData;
 use Drupal\eca\Plugin\DataType\DataTransferObject;
 
 /**
@@ -45,6 +46,9 @@ trait PluginFormTrait {
     if ($value instanceof DataTransferObject) {
       $value = $value->getValue();
     }
+    if ($value instanceof StringData) {
+      $value = $value->getCastedValue();
+    }
     return is_scalar($value) ? (string) $value : $default;
   }