Skip to content

Commit

Permalink
Merge pull request #79 from openeuropa/OPENEUROPA-2416
Browse files Browse the repository at this point in the history
OPENEUROPA-2416: Allow to define which view modes are embedable.
  • Loading branch information
brummbar authored Feb 20, 2020
2 parents d091010 + d6bd8d9 commit 324f738
Show file tree
Hide file tree
Showing 16 changed files with 472 additions and 58 deletions.
46 changes: 43 additions & 3 deletions modules/oe_media_embed/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

The OpenEuropa Media Embed module allows the embedding of Media entities into content in an agnostic (non-Drupal) way.

To this end, it comes with two main elements: the WYSIWYG embed button and the filter plugin.
To this end, it comes with two main elements: the WYSIWYG embed button and the filter plugin. On top of that, it allows
the site administrators to define which available view displays are also available to be embedded.

## WYSIWYG button

Using the media embed WYSIWYG button, editors can select media entities that they wish to embed. Upon selecting the media entity, an oEmbed-based embed code is
inserted in the content. This code follows the oEmbed protocol and is therefore understandable by other clients as well. An example embed code:
Expand All @@ -15,7 +18,44 @@ inserted in the content. This code follows the oEmbed protocol and is therefore

Where `118a06e9-e7df-4b7b-8ab2-5f5addc2f0b3` is the UUID of the media entity.

This embed code is transformed into the rendered entity by the filter plugin `FilterMediaEmbed`. Adding this to a text format will replace the embed tags with the rendered media entity.

Moreover, we have the [OpenEuropa oEmbed component](https://github.com/openeuropa/oe_oembed) which will be used when a site expects its content to be read by external systems that
Moreover, we have the [OpenEuropa oEmbed component][1] which will be used when a site expects its content to be read by external systems that
need to understand the embed codes. Essentially, it acts as an oEmbed provider for the media resources on the site.

## Text filter

The embed code provided by the WYSIWYG button is transformed into the rendered entity by the filter plugin `FilterMediaEmbed`.
Adding this to a text format will replace the embed tags with the rendered media entity.


## Embeddable view displays

Site administrators will need to define which available view modes are also available to be embedded via the tools described above.
This is done by selecting the available view displays on the display mode configuration page for each available media bundle.

## Usage

In order to use the functionalities of the module, follow the next steps:

1) Create a text format.
You can do so by navigating to `/admin/config/content/formats` and clicking the "Add text format button". More information
is available on the official [documentation][2].

2) Add the Media Embed button to your Active toolbar.
You can do that while creating your text format or by navigating to the text format configuration form (`/admin/config/content/formats/manage/TEXT_FORMAT_ID`).
Make sure you select CKEditor as the Text editor for your text format and move the "Media" button from the *available buttons* section to the Active toolbar.

3) Enable the "Embeds media entities using the oEmbed format" filter.
This filter needs to be enabled and placed last in the Filter processing order.
(**WARNING**: This is very important if you want the oEmbed specific urls to be converted into internal aliases)

4) Make view displays embeddable.
Once the previous steps are done, navigate to the display mode configuration of the bundle you wish to be embeddable and select which of
the available view displays will be available for embedding. E.g., in order to configure which of the view displays of the Image media type
are available for embedding, you will need to navigate to `/admin/structure/media/manage/image/display`.



[1]: https://github.com/openeuropa/oe_oembed
[2]: https://www.drupal.org/docs/user_guide/en/structure-text-format-config.html

Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,11 @@ oe_media_embed.settings:
service_url:
type: uri
label: 'oEmbed service URL'

core.entity_view_display.*.*.*.third_party.oe_media_embed:
type: mapping
label: 'OpenEuropa embed settings'
mapping:
embeddable:
type: boolean
label: 'Embeddable'
1 change: 0 additions & 1 deletion modules/oe_media_embed/oe_media_embed.info.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package: OpenEuropa
type: module
core: 8.x
dependencies:
- oe_media:oe_media
- drupal:views
- media_avportal:media_avportal
- embed:embed
Expand Down
93 changes: 93 additions & 0 deletions modules/oe_media_embed/oe_media_embed.module
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,102 @@

declare(strict_types = 1);

use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Form\FormStateInterface;

/**
* Implements hook_ckeditor_css_alter().
*/
function oe_media_embed_ckeditor_css_alter(&$css, $editor) {
$css[] = drupal_get_path('module', 'oe_media_embed') . '/css/ckeditor_embed.css';
}

/**
* Implements hook_form_FORM_ID_alter().
*
* Alters the entity view display edit form for Media entities to add an element
* that allows to select which view modes can be used for embedding in the
* WYSIWYG.
*/
function oe_media_embed_form_entity_view_display_edit_form_alter(&$form, FormStateInterface $form_state, $form_id) {
/** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $entity */
$entity = $form_state->getFormObject()->getEntity();
// We only care about media entities.
if ($entity->getTargetEntityTypeId() !== 'media') {
return;
}
// We only add to the Custom Display Settings, if it exists.
if (!isset($form['modes'])) {
return;
}

// Gather which view displays are currently available.
$options = [];
$default_value = [];
foreach (_oe_media_embed_get_enabled_display_options($entity) as $id => $details) {
$options[$id] = $details['label'];
$default_value[$id] = $details['embeddable'] ? $id : 0;
}
$form['modes']['embeddable_displays'] = [
'#type' => 'checkboxes',
'#title' => t('Embeddable view displays'),
'#description' => t('Select which of the view modes should be available when embedding a media entity.'),
'#options' => $options,
'#default_value' => $default_value,
];

$form['actions']['submit']['#submit'][] = '_oe_media_embed_save_embeddable_displays';
}

/**
* Custom submit method for entity view display edit forms.
*
* We store whether an entity view display should be embeddable or not.
*/
function _oe_media_embed_save_embeddable_displays(array &$form, FormStateInterface $form_state) {
if (!$form_state->getValue('embeddable_displays')) {
return;
}
$display = $form_state->getFormObject()->getEntity();
/** @var \Drupal\Core\Entity\EntityStorageInterface $storage */
$storage = \Drupal::entityTypeManager()->getStorage($display->getEntityTypeId());
foreach ($form_state->getValue('embeddable_displays') as $mode => $value) {
/** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $view_display */
$view_display = $storage->load($display->getTargetEntityTypeId() . '.' . $display->getTargetBundle() . '.' . $mode);
// Only save if the value has changed.
if ($view_display->getThirdPartySetting('oe_media_embed', 'embeddable') !== $value) {
$view_display->setThirdPartySetting('oe_media_embed', 'embeddable', $value);
$view_display->save();
}
}

}

/**
* Returns the available entity view displays and if they are embeddable or not.
*
* @param \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display
* The display being edited.
*
* @return array
* A list of enabled view displays.
*/
function _oe_media_embed_get_enabled_display_options(EntityViewDisplayInterface $display) {
$available_options = [];
// Retrieve all available displays for the target entity type.
$available_display_modes = \Drupal::service('entity_display.repository')->getViewModeOptions($display->getTargetEntityTypeId());

/** @var \Drupal\Core\Entity\EntityStorageInterface $storage */
$storage = \Drupal::entityTypeManager()->getStorage($display->getEntityTypeId());
foreach ($available_display_modes as $mode => $label) {
/** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $view_display */
$view_display = $storage->load($display->getTargetEntityTypeId() . '.' . $display->getTargetBundle() . '.' . $mode);
if ($view_display && $view_display->status()) {
$available_options[$mode] = [
'label' => $label,
'embeddable' => $view_display->getThirdPartySetting('oe_media_embed', 'embeddable'),
];
}
}
return $available_options;
}
28 changes: 28 additions & 0 deletions modules/oe_media_embed/oe_media_embed.post_update.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

/**
* @file
* Post update functions for OpenEuropa Media module.
*/

declare(strict_types = 1);

use Drupal\Core\Entity\Entity\EntityViewDisplay;

/**
* Make view modes that are already available embeddable by default.
*/
function oe_media_embed_post_update_00001(): void {
$available_view_display_ids = \Drupal::entityQuery('entity_view_display')
->condition('targetEntityType', 'media')
->condition('status', TRUE)
->execute();
$available_view_displays = EntityViewDisplay::loadMultiple($available_view_display_ids);
/** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $view_display */
foreach ($available_view_displays as $view_display) {
if ($view_display->getThirdPartySetting('oe_media_embed', 'embeddable') === NULL) {
$view_display->setThirdPartySetting('oe_media_embed', 'embeddable', TRUE);
$view_display->save();
}
}
}
Loading

0 comments on commit 324f738

Please sign in to comment.