You are here

class ImageEmbedDataFormatter in Formatter Suite 8

Embeds an image as a data URL instead of a file URL.

Normally, images are included on a page by using an <img> tag with a file URL that causes the browser to issue another HTTP request to get the file. When there are a large number of images on a page, the latency inherent in HTTP requests adds up and can substantially slow down page loads.

This formatter optionally replaces file URLs with data URLs that include the base 64 encoding of the image directly within the page. There is no need for a further HTTP request, which reduces load time wasted on latency. The downside is that the image data can be up to 3 times larger when base 64 encoded. This makes the page itself larger and delays it being loaded. Often, though, the savings in reduced latency is much greater than the time lost in longer page load times.

This is most effective when showing a large number of small images, such as image lists with thumbnails. It can also be effective when a page has only a few images to convert to data URLs, even if they are large.

This formatter's options select maximum image width and height for embedding as a data URL. Images larger than this are left as file URLs.

Plugin annotation


@FieldFormatter(
  id          = "formatter_suite_image_embed_data",
  label       = @Translation("Formatter Suite - Image with embedded data URL"),
  weight      = 1001,
  field_types = {
    "image",
  }
)

Hierarchy

Expanded class hierarchy of ImageEmbedDataFormatter

Related topics

File

src/Plugin/Field/FieldFormatter/ImageEmbedDataFormatter.php, line 46

Namespace

Drupal\formatter_suite\Plugin\Field\FieldFormatter
View source
class ImageEmbedDataFormatter extends ImageFormatter {

  /*---------------------------------------------------------------------
   *
   * Configuration.
   *
   *---------------------------------------------------------------------*/

  /**
   * {@inheritdoc}
   */
  public static function defaultSettings() {
    return array_merge([
      'maximumEmbedWidth' => '',
      'maximumEmbedHeight' => '',
    ], parent::defaultSettings());
  }

  /**
   * {@inheritdoc}
   */
  public function settingsSummary() {

    // Get current settings.
    $maximumEmbedWidth = $this
      ->getSetting('maximumEmbedWidth');
    $maximumEmbedHeight = $this
      ->getSetting('maximumEmbedHeight');

    // Sanitize & validate.
    //
    // Security: The maximum embed width and height have been entered by
    // an administrator. They both should be simple integers and should
    // not include any HTML or HTML entities.
    //
    // Parsing these as integers ignores any extra text that may be in
    // the value.
    if (isset($maximumEmbedWidth) === TRUE) {
      $maximumEmbedWidth = intval($maximumEmbedWidth);
    }
    else {
      $maximumEmbedWidth = 0;
    }
    if (isset($maximumEmbedHeight) === TRUE) {
      $maximumEmbedHeight = intval($maximumEmbedHeight);
    }
    else {
      $maximumEmbedHeight = 0;
    }

    // Summarize.
    $summary = [];
    $summary[] = $this
      ->t('Embed image data URL');
    if ($maximumEmbedWidth > 0 && $maximumEmbedHeight > 0) {
      $summary[] = $this
        ->t('&nbsp;&nbsp;for width &le; @maximumEmbedWidth &amp; height &le; @maximumEmbedHeight.', [
        '@maximumEmbedWidth' => $maximumEmbedWidth,
        '@maximumEmbedHeight' => $maximumEmbedHeight,
      ]);
    }
    elseif ($maximumEmbedWidth > 0) {
      $summary[] = $this
        ->t('&nbsp;&nbsp;for width &le; @maximumEmbedWidth &amp; any height.', [
        '@maximumEmbedWidth' => $maximumEmbedWidth,
      ]);
    }
    elseif ($maximumEmbedHeight > 0) {
      $summary[] = $this
        ->t('&nbsp;&nbsp;for any width &amp; height &le; @maximumEmbedHeight.', [
        '@maximumEmbedHeight' => $maximumEmbedHeight,
      ]);
    }
    else {
      $summary[] = $this
        ->t('&nbsp;&nbsp;for any width &amp; height.');
    }
    $summary = array_merge($summary, parent::settingsSummary());
    return $summary;
  }

  /*---------------------------------------------------------------------
   *
   * Settings form.
   *
   *---------------------------------------------------------------------*/

  /**
   * Returns a brief description of the formatter.
   *
   * @return string
   *   Returns a brief translated description of the formatter.
   */
  protected function getDescription() {
    return $this
      ->t("Embed image pixels directly within the page by using a data URL instead of a file URL. This reduces the browser's time spent requesting images, but increases the page size and its download time. It is primarily a good trade-off when images are small, such as for thumbnails.");
  }

  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $formState) {

    // Start with the parent form.
    $elements = parent::settingsForm($form, $formState);

    // Add branding.
    $elements = Branding::addFieldFormatterBranding($elements);
    $elements['#attached']['library'][] = 'formatter_suite/formatter_suite.fieldformatter';

    // Add description.
    $elements['description'] = [
      '#type' => 'html_tag',
      '#tag' => 'div',
      '#value' => $this
        ->getDescription(),
      '#weight' => -1000,
      '#attributes' => [
        'class' => [
          'formatter_suite-settings-description',
        ],
      ],
    ];
    $weight = 100;

    // Prompt for each setting.
    $elements['sectionBreak'] = [
      '#markup' => '<div class="formatter_suite-section-break"></div>',
      '#weight' => $weight++,
    ];
    $elements['maximumEmbedWidth'] = [
      '#type' => 'number',
      '#title' => $this
        ->t('Maximum width'),
      '#size' => 10,
      '#default_value' => $this
        ->getSetting('maximumEmbedWidth'),
      '#weight' => $weight++,
    ];
    $elements['maximumEmbedHeight'] = [
      '#type' => 'number',
      '#title' => $this
        ->t('Maximum height'),
      '#size' => 10,
      '#default_value' => $this
        ->getSetting('maximumEmbedHeight'),
      '#description' => $this
        ->t("Images this size or smaller will be embedded, while larger images will be left as file URLs. If a maximum is empty or zero, that dimension has no maximum."),
      '#weight' => $weight++,
    ];
    return $elements;
  }

  /*---------------------------------------------------------------------
   *
   * View.
   *
   *---------------------------------------------------------------------*/

  /**
   * {@inheritdoc}
   */
  public function viewElements(FieldItemListInterface $items, $langCode) {

    // Get current settings.
    $maximumEmbedWidth = $this
      ->getSetting('maximumEmbedWidth');
    $maximumEmbedHeight = $this
      ->getSetting('maximumEmbedHeight');

    // Sanitize & validate.
    //
    // Security: The maximum embed width and height have been entered by
    // an administrator. They both should be simple integers and should
    // not include any HTML or HTML entities.
    //
    // Parsing these as integers ignores any extra text that may be in
    // the value.
    if (isset($maximumEmbedWidth) === TRUE) {
      $maximumEmbedWidth = (int) $maximumEmbedWidth;
    }
    else {
      $maximumEmbedWidth = 0;
    }
    if (isset($maximumEmbedHeight) === TRUE) {
      $maximumEmbedHeight = (int) $maximumEmbedHeight;
    }
    else {
      $maximumEmbedHeight = 0;
    }

    // The parent image module does very little processing within the
    // formatter. Instead, it sets a theme template and later processing
    // of the template sets up the image's URL, including possibly use of
    // an image style.
    //
    // Let the parent class do its processing. The returned array has one
    // entry per item and a configuration that invokes the image module's
    // 'image_formatter' theme.
    //
    // If the items list is empty, the parent class looks for a default
    // image for the field and, if any, fills it in. The resulting
    // $elements array will only be empty if there was no default image.
    $elements = parent::viewElements($items, $langCode);
    if (empty($elements) === TRUE) {
      return [];
    }

    // Loop through results from the parent class and swap the theme
    // to point to our own 'formatter_suite_image_formatter'. Add the
    // configured maximum width and height. Then let theme handling
    // take over to handle inlining images.
    foreach ($elements as $delta => $element) {
      if (isset($elements[$delta]) === TRUE && isset($elements[$delta]['#theme']) === TRUE) {
        $elements[$delta]['#theme'] = 'formatter_suite_image_embed_formatter';
        $elements[$delta]['#maximumEmbedWidth'] = $maximumEmbedWidth;
        $elements[$delta]['#maximumEmbedHeight'] = $maximumEmbedHeight;
      }
    }
    return $elements;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
EntityReferenceFormatterBase::prepareView public function Loads the entities referenced in that field across all the entities being viewed. Overrides FormatterBase::prepareView
EntityReferenceFormatterBase::view public function Overrides FormatterBase::view
FileFormatterBase::checkAccess protected function Checks access to the given entity. Overrides EntityReferenceFormatterBase::checkAccess
FileFormatterBase::needsEntityLoad protected function Returns whether the entity referenced by an item needs to be loaded. Overrides EntityReferenceFormatterBase::needsEntityLoad 1
FormatterBase::$fieldDefinition protected property The field definition.
FormatterBase::$label protected property The label display setting.
FormatterBase::$settings protected property The formatter settings. Overrides PluginSettingsBase::$settings
FormatterBase::$viewMode protected property The view mode.
FormatterBase::getFieldSetting protected function Returns the value of a field setting.
FormatterBase::getFieldSettings protected function Returns the array of field settings.
FormatterBase::isApplicable public static function Returns if the formatter can be used for the provided field. Overrides FormatterInterface::isApplicable 14
ImageEmbedDataFormatter::defaultSettings public static function Defines the default settings for this plugin. Overrides ImageFormatter::defaultSettings
ImageEmbedDataFormatter::getDescription protected function Returns a brief description of the formatter.
ImageEmbedDataFormatter::settingsForm public function Returns a form to configure settings for the formatter. Overrides ImageFormatter::settingsForm
ImageEmbedDataFormatter::settingsSummary public function Returns a short summary for the current formatter settings. Overrides ImageFormatter::settingsSummary
ImageEmbedDataFormatter::viewElements public function Builds a renderable array for a field value. Overrides ImageFormatter::viewElements
ImageFormatter::$currentUser protected property The current user.
ImageFormatter::$imageStyleStorage protected property The image style entity storage.
ImageFormatter::calculateDependencies public function Calculates dependencies for the configured plugin. Overrides PluginSettingsBase::calculateDependencies
ImageFormatter::create public static function Creates an instance of the plugin. Overrides FormatterBase::create 1
ImageFormatter::onDependencyRemoval public function Informs the plugin that some configuration it depends on will be deleted. Overrides PluginSettingsBase::onDependencyRemoval
ImageFormatter::__construct public function Constructs an ImageFormatter object. Overrides FormatterBase::__construct 1
ImageFormatterBase::getEntitiesToView protected function Returns the referenced entities for display. Overrides EntityReferenceFormatterBase::getEntitiesToView
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 3
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
PluginSettingsBase::$defaultSettingsMerged protected property Whether default settings have been merged into the current $settings.
PluginSettingsBase::$thirdPartySettings protected property The plugin settings injected by third party modules.
PluginSettingsBase::getSetting public function Returns the value of a setting, or its default value if absent. Overrides PluginSettingsInterface::getSetting
PluginSettingsBase::getSettings public function Returns the array of settings, including defaults for missing settings. Overrides PluginSettingsInterface::getSettings
PluginSettingsBase::getThirdPartyProviders public function Gets the list of third parties that store information. Overrides ThirdPartySettingsInterface::getThirdPartyProviders
PluginSettingsBase::getThirdPartySetting public function Gets the value of a third-party setting. Overrides ThirdPartySettingsInterface::getThirdPartySetting
PluginSettingsBase::getThirdPartySettings public function Gets all third-party settings of a given module. Overrides ThirdPartySettingsInterface::getThirdPartySettings
PluginSettingsBase::mergeDefaults protected function Merges default settings values into $settings.
PluginSettingsBase::setSetting public function Sets the value of a setting for the plugin. Overrides PluginSettingsInterface::setSetting
PluginSettingsBase::setSettings public function Sets the settings for the plugin. Overrides PluginSettingsInterface::setSettings
PluginSettingsBase::setThirdPartySetting public function Sets the value of a third-party setting. Overrides ThirdPartySettingsInterface::setThirdPartySetting
PluginSettingsBase::unsetThirdPartySetting public function Unsets a third-party setting. Overrides ThirdPartySettingsInterface::unsetThirdPartySetting
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.