Skip to content

Instantly share code, notes, and snippets.

@lauriii
Created September 8, 2022 06:16
Show Gist options
  • Save lauriii/c3f0308de3ee0807a625404d6b9fe404 to your computer and use it in GitHub Desktop.
Save lauriii/c3f0308de3ee0807a625404d6b9fe404 to your computer and use it in GitHub Desktop.
diff --git a/css/next.site_preview.iframe.css b/css/next.site_preview.iframe.css
index 0803bcb..1ee5e39 100644
--- a/css/next.site_preview.iframe.css
+++ b/css/next.site_preview.iframe.css
@@ -33,7 +33,7 @@
color: #325e1c;
}
-.next-site-preview-toolbar .operations .live-link .button {
+.next-site-preview-toolbar .operations .live-link .preview-link .button {
margin-top: 0;
margin-bottom: 0;
}
diff --git a/next.links.task.yml b/next.links.task.yml
index 16545c5..7d04de5 100644
--- a/next.links.task.yml
+++ b/next.links.task.yml
@@ -18,3 +18,9 @@ next.settings:
route_name: next.settings
base_route: next.settings
weight: 20
+
+entity.node.headless_preview:
+ title: Preview
+ route_name: entity.node.headless_preview
+ base_route: entity.node.canonical
+ weight: 5
diff --git a/next.routing.yml b/next.routing.yml
index 35be98f..5ce1a5e 100644
--- a/next.routing.yml
+++ b/next.routing.yml
@@ -16,3 +16,18 @@ next.validate_preview_url:
requirements:
_access: 'TRUE'
_format: 'json'
+
+entity.node.headless_preview:
+ path: '/node/{node}/site-preview'
+ defaults:
+ _title_callback: '\Drupal\next\Controller\SitePreviewController::nodePreviewTitle'
+ _controller: '\Drupal\next\Controller\SitePreviewController::nodePreview'
+ requirements:
+ _entity_access: node.view
+ _module_dependencies: content_moderation
+ options:
+ _node_operation_route: TRUE
+ _admin_route: TRUE
+ parameters:
+ node:
+ type: entity:node
diff --git a/src/Controller/SitePreviewController.php b/src/Controller/SitePreviewController.php
new file mode 100644
index 0000000..5b33bf1
--- /dev/null
+++ b/src/Controller/SitePreviewController.php
@@ -0,0 +1,100 @@
+<?php
+
+namespace Drupal\next\Controller;
+
+use Drupal\Core\Controller\ControllerBase;
+use Drupal\node\Entity\Node;
+use Drupal\next\NextEntityTypeManager;
+use Drupal\next\Plugin\SitePreviewerManagerInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Defines a controller for the site preview of a node.
+ *
+ * @internal
+ * This is an internal part of Acquia CMS Headless and may be changed or
+ * removed at any time without warning. External code should not extend or
+ * use this class in any way!
+ */
+class SitePreviewController extends ControllerBase
+{
+ /**
+ * The next entity type manager.
+ *
+ * @var \Drupal\next\NextEntityTypeManager
+ */
+ protected $nextEntityTypeManager;
+
+ /**
+ * The site previewer manager.
+ *
+ * @var \Drupal\next\Plugin\SitePreviewerManagerInterface
+ */
+ protected $sitePreviewerManager;
+
+ public function __construct(NextEntityTypeManager $nextEntityTypeManager, SitePreviewerManagerInterface $sitePreviewerManager)
+ {
+ $this->nextEntityTypeManager = $nextEntityTypeManager;
+ $this->sitePreviewerManager = $sitePreviewerManager;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container)
+ {
+ return new static(
+ $container->get('next.entity_type.manager'),
+ $container->get('plugin.manager.next.site_previewer')
+ );
+ }
+
+ /**
+ * Displays the node title for preview.
+ * @param Node $node [description]
+ * @return string [description]
+ */
+ public function nodePreviewTitle(Node $node)
+ {
+ return 'Preview: ' . $node->getTitle();
+ }
+
+ /**
+ * Displays the next.js site preview of a node.
+ */
+ public function nodePreview(Node $node)
+ {
+ $storage = \Drupal::entityTypeManager()->getStorage($node->getEntityTypeId());
+ $revision = $storage->loadRevision($storage->getLatestRevisionId($node->id()));
+
+ $next_entity_type_config = $this->nextEntityTypeManager->getConfigForEntityType($revision->getEntityTypeId(), $revision->bundle());
+ $sites = $next_entity_type_config->getSiteResolver()->getSitesForEntity($revision);
+ if (!count($sites)) {
+ throw new \Exception('Next.js sites for the entity could not be resolved.');
+ }
+
+ $config = $this->config('next.settings');
+ $site_previewer_id = $config->get('site_previewer') ?? 'iframe';
+
+ /** @var \Drupal\next\Plugin\SitePreviewerInterface $site_previewer */
+ $site_previewer = $this->sitePreviewerManager->createInstance($site_previewer_id, $config->get('site_previewer_configuration') ?? []);
+ if (!$site_previewer) {
+ throw new PluginNotFoundException('Invalid site previewer.');
+ }
+
+ // Build preview.
+ $preview = $site_previewer->render($revision, $sites);
+
+ $context = [
+ 'plugin' => $site_previewer,
+ 'entity' => $revision,
+ 'sites' => $sites,
+ ];
+
+ // Allow modules to alter the preview.
+ $this->moduleHandler()->alter('next_site_preview', $preview, $context);
+
+ return $preview;
+ }
+}
+
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment