Skip to content
Snippets Groups Projects
Commit 3d7fa0c7 authored by Merlin Axel Rutz's avatar Merlin Axel Rutz Committed by Italo Mairo
Browse files

Issue #3068719 by axel.rutz, itamair, anruether: Attachments and Cacheability...

Issue #3068719 by axel.rutz, itamair, anruether: Attachments and Cacheability dropped for Leaflet (embeded|ajax) popups
parent 39737009
No related branches found
No related tags found
No related merge requests found
......@@ -23,13 +23,17 @@
var content = $('[data-leaflet-ajax-popup]', e.popup._contentNode);
if (content.length) {
var url = content.data('leaflet-ajax-popup');
$.get(url, function(response) {
if (response) {
e.popup.setContent(response)
}
});
Drupal.ajax({url: url}).execute();
}
});
// Attach drupal behaviors on new content.
Drupal.Leaflet[mapid].lMap.on('popupopen', function(e) {
var element = e.popup._contentNode;
$(element).once('leaflet-popup-behaviors-attached').each(function () {
Drupal.attachBehaviors(this, drupalSettings);
})
});
});
$.each(settings.leaflet, function(m, data) {
......
......@@ -2,6 +2,8 @@
namespace Drupal\leaflet_views\Controller;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Render\HtmlResponse;
......@@ -75,15 +77,72 @@ class LeafletAjaxPopupController extends ControllerBase {
* @param string $langcode
* The langcode to render the entity by.
*
* @return \Drupal\Core\Render\HtmlResponse
* @return \Symfony\Component\HttpFoundation\Response
* The Response to return.
*/
public function popupBuild(EntityInterface $entity, $view_mode, $langcode = NULL) {
$entity_view_builder = $this->entityManager->getViewBuilder($entity->getEntityTypeId());
$build = $entity_view_builder->view($entity, $view_mode, $langcode);
$response = new HtmlResponse();
$response->setContent($this->renderer->renderRoot($build));
$response = new AjaxResponse();
$response->addCommand(new ReplaceCommand($this->getPopupIdentifierSelector($entity->getEntityTypeId(), $entity->id(), $view_mode, $langcode), $build));
return $response;
}
/**
* Get popup identifier.
*
* @param $entityType
* The entity type.
* @param $entityId
* The entity id.
* @param $viewMode
* The view mode.
* @param $langcode
* The langcode.
*
* @return string
* The identifier.
*/
public static function getPopupIdentifier($entityType, $entityId, $viewMode, $langcode): string {
return "$entityType-$entityId-$viewMode-$langcode";
}
/**
* Get popup identifier attribute.
*
* @param $entityType
* The entity type.
* @param $entityId
* The entity id.
* @param $viewMode
* The view mode.
* @param $langcode
* The langcode.
*
* @return string
* The identifier selector.
*/
public static function getPopupIdentifierAttribute($entityType, $entityId, $viewMode, $langcode) {
return sprintf('data-leaflet-popup-ajax-entity="%s"', self::getPopupIdentifier($entityType, $entityId, $viewMode, $langcode));
}
/**
* Get popup identifier selector.
*
* @param $entityType
* The entity type.
* @param $entityId
* The entity id.
* @param $viewMode
* The view mode.
* @param $langcode
* The langcode.
*
* @return string
* The identifier selector.
*/
public static function getPopupIdentifierSelector($entityType, $entityId, $viewMode, $langcode) {
return sprintf('[%s]', self::getPopupIdentifierAttribute($entityType, $entityId, $viewMode, $langcode));
}
}
......@@ -4,9 +4,12 @@ namespace Drupal\leaflet_views\Plugin\views\style;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Field\FieldTypePluginManagerInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Render\RenderContext;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Entity\Plugin\DataType\EntityAdapter;
use Drupal\Core\Form\FormStateInterface;
use Drupal\leaflet_views\Controller\LeafletAjaxPopupController;
use Drupal\search_api\Datasource\DatasourceInterface;
use Drupal\search_api\Entity\Index;
use Drupal\Core\Url;
......@@ -665,6 +668,9 @@ class LeafletMap extends StylePluginBase implements ContainerFactoryPluginInterf
$data = [];
// Collect bubbleable metadata when doing early rendering.
$build_for_bubbleable_metadata = [];
// Always render the map, otherwise ...
$leaflet_map_style = !isset($this->options['leaflet_map']) ? $this->options['map'] : $this->options['leaflet_map'];
$map = leaflet_map_get_info($leaflet_map_style);
......@@ -754,18 +760,26 @@ class LeafletMap extends StylePluginBase implements ContainerFactoryPluginInterf
case '#rendered_entity':
$build = $this->entityManager->getViewBuilder($entity->getEntityTypeId())
->view($entity, $this->options['view_mode'], $langcode);
$description = $this->renderer->renderPlain($build);
$render_context = new RenderContext();
$description = $this->renderer->executeInRenderContext($render_context, function () use (&$build) {
return $this->renderer->render($build, TRUE);
});
if (!$render_context->isEmpty()) {
$render_context->update($build_for_bubbleable_metadata);
}
break;
case '#rendered_entity_ajax':
$parameters = [
'entity_type' => $entity->getEntityTypeId(),
'entity_type' => $entity_type,
'entity' => $entity->id(),
'view_mode' => $this->options['view_mode'],
'langcode' => $langcode,
];
$url = Url::fromRoute('leaflet_views.ajax_popup', $parameters, ['absolute' => TRUE]);
$description = sprintf('<div class="leaflet-ajax-popup" data-leaflet-ajax-popup="%s"></div>', $url->toString());
$description = sprintf('<div class="leaflet-ajax-popup" data-leaflet-ajax-popup="%s" %s></div>',
$url->toString(), LeafletAjaxPopupController::getPopupIdentifierAttribute($entity_type, $entity->id(), $this->options['view_mode'], $langcode));
$build_for_bubbleable_metadata['#attached']['library'][] = 'drupal/ajax';
break;
default:
......@@ -851,7 +865,11 @@ class LeafletMap extends StylePluginBase implements ContainerFactoryPluginInterf
// Allow other modules to add/alter the map js settings.
$this->moduleHandler->alter('leaflet_map_view_style', $js_settings, $this);
return $this->leafletService->leafletRenderMap($js_settings['map'], $js_settings['features'], $this->options['height'] . 'px');
$build = $this->leafletService->leafletRenderMap($js_settings['map'], $js_settings['features'], $this->options['height'] . 'px');
BubbleableMetadata::createFromRenderArray($build)
->merge(BubbleableMetadata::createFromRenderArray($build_for_bubbleable_metadata))
->applyTo($build);
return $build;
}
/**
......
......@@ -3,6 +3,8 @@
namespace Drupal\leaflet\Plugin\Field\FieldFormatter;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Render\RenderContext;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
......@@ -314,6 +316,7 @@ class LeafletDefaultFormatter extends FormatterBase implements ContainerFactoryP
$this->fieldDefinition->getTargetEntityTypeId() => $items->getEntity(),
];
$results = [];
$features = [];
foreach ($items as $delta => $item) {
......@@ -323,18 +326,29 @@ class LeafletDefaultFormatter extends FormatterBase implements ContainerFactoryP
// Eventually set the popup content.
if ($settings['popup']) {
// Construct the renderable array for popup title / text.
// Construct the renderable array for popup title / text. As we later
// convert that to plain text, losing attachments and cacheability, save
// them to $results.
$build = [];
if ($this->getSetting('popup_content')) {
$popup_content = $this->token->replace($this->getSetting('popup_content'), $token_context);
$bubbleable_metadata = new BubbleableMetadata();
$popup_content = $this->token->replace($this->getSetting('popup_content'), $token_context, [], $bubbleable_metadata);
$build[] = [
'#markup' => $popup_content,
];
$bubbleable_metadata->applyTo($results);
}
// We need a string for using it inside the popup.
$build = $this->renderer->renderPlain($build);
$feature['popup'] = !empty($build) ? $build : $entity->label();;
// We need a string for using it inside the popup. Save attachments and
// cacheability to $results.
$render_context = new RenderContext();
$rendered = $this->renderer->executeInRenderContext($render_context, function () use (&$build) {
return $this->renderer->render($build, TRUE);
});
$feature['popup'] = !empty($rendered) ? $rendered : $entity->label();
if (!$render_context->isEmpty()) {
$render_context->update($results);
}
}
// Add/merge eventual map icon definition from hook_leaflet_map_info.
......@@ -368,7 +382,6 @@ class LeafletDefaultFormatter extends FormatterBase implements ContainerFactoryP
// Allow other modules to add/alter the map js settings.
$this->moduleHandler->alter('leaflet_default_map_formatter', $js_settings, $items);
$results = [];
if (!empty($settings['multiple_map'])) {
foreach ($js_settings['features'] as $k => $feature) {
$map = $js_settings['map'];
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment