web-dev-qa-db-fra.com

Comment afficher par programmation un bloc?

Je développe un site en utilisant Drupal 8 beta-14. J'ai créé un bloc d'affichage de différents termes et maintenant je veux l'afficher en utilisant du code. Comment puis-je l'afficher par programme? I utilisé pour le faire dans Drupal 7 en utilisant ce code mais je suis confus à propos de Drupal 8.

$block = module_invoke('block', 'block_view', '4');
$text_block = render($block['content']);
35
rashidkhan

Il existe deux types de blocs et la méthode de rendu des deux est un peu différente:

Blocs de contenu

Les blocs de contenu sont des blocs que vous créez dans l'interface. Ils ressemblent beaucoup à des structures de données configurables par noeuds, avec des champs, etc.

$bid = ??? // Get the block id through config, SQL or some other means
$block = \Drupal\block_content\Entity\BlockContent::load($bid);
$render = \Drupal::entityTypeManager()->
  getViewBuilder('block_content')->view($block);
return $render;

Blocs de plugin

Les blocs peuvent également être des plugins, définis dans différents modules. Un exemple pourrait être le bloc de fil d'Ariane. Si vous voulez les rendre, vous devrez utiliser le gestionnaire de plugins de blocs.

$block_manager = \Drupal::service('plugin.manager.block');
// You can hard code configuration or you load from settings.
$config = [];
$plugin_block = $block_manager->createInstance('system_breadcrumb_block', $config);
// Some blocks might implement access check.
$access_result = $plugin_block->access(\Drupal::currentUser());
// Return empty render array if user doesn't have access.
// $access_result can be boolean or an AccessResult class
if (is_object($access_result) && $access_result->isForbidden() || is_bool($access_result) && !$access_result) {
  // You might need to add some cache tags/contexts.
  return [];
}
$render = $plugin_block->build();
// In some cases, you need to add the cache tags/context depending on
// the block implemention. As it's possible to add the cache tags and
// contexts in the render method and in ::getCacheTags and 
// ::getCacheContexts methods.
return $render;

Entités de configuration

Les blocs sont partagés pour les deux types, c'est qu'une fois que vous les insérez dans une région, vous allez créer une entité de configuration qui possède tous les paramètres du bloc. Dans certains cas, il sera plus utile de gérer les entités de configuration. Étant donné que le même bloc peut être placé dans plusieurs régions avec et avec une configuration différente, il peut être plus difficile d'utiliser les entités de configuration de bloc. La bonne chose est que vous voudrez peut-être rendre un bloc avec une configuration spécifique, la mauvaise chose est que les identifiants de configuration peuvent changer en jouant avec l'interface, donc le code pourrait ne pas fonctionner après avoir laissé les utilisateurs utiliser l'interface de bloc.

$block = \Drupal\block\Entity\Block::load('config.id');
$render = \Drupal::entityTypeManager()
  ->getViewBuilder('block')
  ->view($block);
return $render;
76
googletorp

Pour afficher uniquement votre bloc dans vos modèles avec un prétraitement, la meilleure façon est

$block = \Drupal\block\Entity\Block::load('my_block_id');
$variables['My_region'] = \Drupal::entityManager()
          ->getViewBuilder('block')
          ->view($block);

Et dans votre page.html.twig Ou node.html.twig Ou xxx.html.twig Utilisez votre variable My_region comme ceci:

{% if page.My_region %}
    {{ page.My_region }}
{% endif %}

Et dans un tableau rendable (module personnalisé) par exemple dans un contrôleur personnalisé dans content ():

public function content() {
    $block = \Drupal\block\Entity\Block::load('my_block_id');
    $block_content = \Drupal::entityManager()
      ->getViewBuilder('block')
      ->view($block);

          return array(
        '#type' => 'container',
        '#attributes' => array(
          'class' => array("Myclass"),
        ),
        "element-content" => $block_content,
        '#weight' => 0,
      );
}

En utilisant drupal_render n'est pas utile car Drupal suppose déjà le rendu en D8 et c'est obsolète . Vous devriez utiliser \Drupal::service('renderer')->renderRoot() à la place.

C'est un peu lourd, il vaut mieux utiliser le système de surface maximale et n'ajoute pas de bloc de charge du pré-processus. Dans le cas de l'utilisation d'un contrôleur dans vos modules, cela semble une utilisation justifiée.

16
woprrr

En plus de la première réponse ... Si vous souhaitez rendre un bloc à partir d'une vue, vous devrez peut-être faire les choses un peu différemment.

$view = views_embed_view('my_view_name', 'my_display_name');

(nom d'affichage par exemple -> block_1)

Puisque nous allons le passer à twig, nous n'avons pas besoin de rendre (en utilisant le service de rendu).

Vous pouvez donc simplement le passer en tant que variable à twig (pour cet exemple, c'est le retour d'un contrôleur):

return [
  ['description' => [
    '#theme' => 'your_theme_hook',
    '#your_variable => $view
  ]
]

dans votre module, vous avez besoin d'un hook_theme () pour votre variable:

function hook_theme($existing, $type, $theme, $path) {
  return array(
    'your_theme_hook' => array(
      'variables' => [
        'your_variable' => NULL,
      ]
    )
  )
}

Et enfin dans votre modèle twig:

{{ your_variable }}
6
CliveCleaves

J'avais besoin d'obtenir le code HTML d'un bloc personnalisé et je l'ai obtenu en utilisant:

$con = \Drupal\block\BlockViewBuilder::lazyBuilder('bartik_search', 'full');
$d   = \Drupal::service('renderer')->renderPlain($con);

print $d->__toString();
5
Eugene
// You need a block_id! to get it just click configure in the desire block and you'll get url like this /admin/structure/block/manage/bartik_search   the last part of the parameter is the block id
$block = \Drupal\block\Entity\Block::load('bartik_search');
$block_content = \Drupal::entityManager()
  ->getViewBuilder('block')
  ->view($block);

return array('#markup' => \Drupal::service('renderer')->renderRoot($block_content));
1
Adi

Fondamentalement, il existe deux types de rendus.

  1. Lorsqu'il existe une instance existante du bloc dans la présentation. le bloc peut être rendu en twig using preprocess as

    $block = Block::load('BLOCK_ID');
    $variables['social_links'] = \Drupal::entityTypeManager()
      ->getViewBuilder('block')
      ->view($block);
    
  2. Il n'y a aucune instance ou configuration pour le bloc. Ensuite, dans le préprocesseur, nous devons créer l'instance, construire le bloc puis le rendre

    $block_manager = \Drupal::service('plugin.manager.block');
    $config = [];
    $plugin_block = $block_manager->createInstance('farmjournal_social_sharing', $config);
    $render = $plugin_block->build();
    $variables['farmjournal_social_sharing'] = render($render);
    
1
Wasim Khan

Semble que cela fonctionne pour les blocs de plugins ..

$block = \Drupal\block\Entity\Block::load('some_block_id_3');
  $pluin = $block->getPlugin();
  $build = $pluin->build();
  $build['#weight'] = 4;
  $form['block'] = $build;
0
Taggart Jensen