...
 
Commits (8)
# Lazy-load [Lazy-load][1] is a simple Drupal module which integrates [bLazy][2]
lazy-loading script via image field *display formatters* and *input-filters* for
inline images and iframes.
This is a simple Drupal module to lazy-load all inline images and/or iframes There is another contributed module utilizing its namesake, [Blazy][3]. Make
defined by content authors in entity content, usually the text-format-enabled sure to check it out, especially if you need more advanced features and support
version of textarea fields. i.e. Node and Block body content. for many features out of the box.
The module currently depends on the [bLazy][1] image script. This module started to fill-in the only area Blazy module lacks of;
**inline-images** and **inline-iframes**. Now, Lazy-load can also be enabled for
each image field as well.
There is another contributed module utilizing its namesake, [Blazy][2]. You can use [Lazy-load][1] module tandem with [Blazy][3], though that is not a
Make sure to check it out, especially if you need more advanced features and requirement.
support for many features out of the box.
This module focuses on the only area Blazy module lacks of; **inline-images** ## Requirements
and **inline-iframes**.
You can still use this module tandem with it, though that is not a requirement. * **[Libraries API][5]** module (Drupal 7 only)
* **bLazy v1.8.2** script as a library item
## Requirements ## Installing Manually
* **[Libraries API][4]** module - [Download bLazy][4] from https://github.com/dinbror/blazy
* **bLazy v1.8.2** script as a library item: - Extract the downloaded file,
[Download bLazy][3] from https://github.com/dinbror/blazy - rename *blazy-master* directory to *blazy*,
1) Extract the downloaded file, - copy the folder into one of the following places that *Libraries API*
2) rename *blazy-master* directory to *blazy*,
3) copy the folder into one of the following places that *Libraries API*
module supports, `sites/all/libraries` (or site-specific libraries folder): module supports, `sites/all/libraries` (or site-specific libraries folder):
i.e.: `sites/all/libraries/blazy/blazy.min.js` i.e.: `sites/all/libraries/blazy/blazy.min.js`
## Installing via Composer
- Run `composer require --prefer-dist composer/installers` to ensure that you
have the `composer/installers` package installed. This package facilitates the
installation of packages into directories other than `/vendor`
(e.g. `/libraries`) using Composer.
- If your `composer.json` doesn’t already have a definition for the libraries
path, define one similar to the one below, depending on your setup:
``` json
"extra": {
"installer-paths": {
"web/sites/all/libraries/{$name}": ["type:drupal-library"]
}
}
```
- Add following to the “repositories” section of `composer.json`:
``` json
"repositories": [
{
"type": "package",
"package": {
"name": "dinbror/blazy",
"version": "1.8.2",
"type": "drupal-library",
"extra": {
"installer-name": "blazy"
},
"source": {
"type": "git",
"url": "https://github.com/dinbror/blazy",
"reference": "1.8.2"
}
}
}
]
```
- Install the required **Blazy** library:
`composer require 'dinbror/blazy:1.8.2'`
- Install this module:
`composer require 'drupal/lazy:^1.0'`
## Installation ## Usage
There are two options to set up for your site to lazy-load images. And both options share the same [settings](/admin/config/content/lazy).
Install the module as usual. More information can be found at 1. Image fields
https://www.drupal.org/docs/7/extend/installing-modules 2. Inline images and Iframes managed in rich-text fields (ckeditor)
## Usage ### Image Fields
1. Go to **Manage display** page of the entity type you want to enable lazy-loading. *i.e. Article*
2. Select the **display** you want the change. *i.e. Teaser*
3. Change the format from `Image` to
`Lazy-load image` to enable lazy-loading for the selected field.
The `Image` formatter settings for
_image style_ and _link image to_ should remain unchanged.
### Inline images and Iframes
1. **Configure** the [text format](/admin/config/content/formats) you want to enable lazy-loading. *i.e. Full HTML*
2. Check **Lazy-load images and IFRAMEs via bLazy** option to enable the filter, and save configuration.
3. Go to [Lazy-load settings](/admin/config/content/lazy).
4. Check the boxes for the inline elements to be lazy-loaded via filter `<img>` `<iframe>`
5. Save configuration
*Repeat steps 1-2 for each text-format you want to enable lazy-loading.*
To disable lazy-loading for specific image or iframes, add **skip-class** to the
class attribute. Default value (no-b-lazy) can be changed in the configuration.
``` html
<img class="no-b-lazy" src="this-image-will-load-normal" alt="">
```
### Blazy plugin can be manupulated in your theme/module javascript:
This modules makes a new text filter available for the text-formats: *Lazy-load* The options in **Blazy configuration** section of the settings form are the default options of the Blazy library. Refer to [Blazy plugin documentation][5] for each setting.
Enable the *Lazy-load* filter for the desired text-formats. i.e. *Full HTML* or #### Get Blazy plugin options.
*Filtered HTML* ```js
let opt = Drupal.settings.lazy ? Drupal.settings.lazy : {};
```
Check out the module configuration at `admin/config/content/lazy`. The default #### Access Blazy's public functions:
settings should work for most developers. Incase they are not, change the | Function | Description |
settings to suit your needs and submit the form. |:--|:--|
| `Drupal.lazy.revalidate();` | Revalidates document for visible images. Useful if you add images with scripting or ajax |
| `Drupal.lazy.load(element(s), force);` | Forces the given element(s) to load if not collapsed. If you also want to load a collapsed/hidden elements you can add true as the second parameter. You can pass a single element or a list of elements. Tested with getElementById, getElementsByClassName, querySelectorAll, querySelector and jQuery selector. |
| `Drupal.lazy.destroy();` | Unbind events and resets image array |
This configuration is used globally for all the text-formats having *Lazy-load*
filter enabled.
## Use Case ## Use Case
...@@ -61,7 +140,8 @@ rewrites the `<img>` and/or `<iframe>` tags in already rendered output to have ...@@ -61,7 +140,8 @@ rewrites the `<img>` and/or `<iframe>` tags in already rendered output to have
them compatible for bLazy script to lazy-load. Since the filtered output is them compatible for bLazy script to lazy-load. Since the filtered output is
cached, there should not be any changes in performance. cached, there should not be any changes in performance.
[1]: http://dinbror.dk/blazy/ [1]: https://www.drupal.org/project/lazy
[2]: https://www.drupal.org/project/blazy [2]: http://dinbror.dk/blazy/
[3]: https://github.com/dinbror/blazy/archive/master.zip [3]: https://www.drupal.org/project/blazy
[4]: https://www.drupal.org/project/libraries [4]: https://github.com/dinbror/blazy/archive/master.zip
[5]: https://www.drupal.org/project/libraries
...@@ -11,10 +11,6 @@ ...@@ -11,10 +11,6 @@
function lazy_configuration_form($form, $form_state) { function lazy_configuration_form($form, $form_state) {
$defaults = variable_get('lazy_filter_defaults'); $defaults = variable_get('lazy_filter_defaults');
$filter_enabled = lazy_is_filter_enabled(); $filter_enabled = lazy_is_filter_enabled();
$description = t('The %filter filter must be enabled for at least one <a href="!path">text-format</a>.', array(
'!path' => url('admin/config/content/formats'),
'%filter' => 'Lazy-load',
));
$form['settings'] = array( $form['settings'] = array(
'#type' => 'fieldset', '#type' => 'fieldset',
...@@ -30,23 +26,30 @@ function lazy_configuration_form($form, $form_state) { ...@@ -30,23 +26,30 @@ function lazy_configuration_form($form, $form_state) {
'iframe' => t('Iframes (%iframe tags)', array('%iframe' => '<iframe>')), 'iframe' => t('Iframes (%iframe tags)', array('%iframe' => '<iframe>')),
), ),
'#default_value' => variable_get('lazy_filter_alter_tag', $defaults['lazy_filter_alter_tag']), '#default_value' => variable_get('lazy_filter_alter_tag', $defaults['lazy_filter_alter_tag']),
'#description' => $filter_enabled ? '' : $description, '#description' => t('Only selected tags will be lazy-loaded in activated text-formats.'),
'#disabled' => !$filter_enabled, '#disabled' => !$filter_enabled,
); );
$form['settings']['lazy_filter_image_fields'] = array(
'#type' => 'checkbox',
'#title' => t('Enable on image fields attached to fieldable entities. For example, content-types, blocks.'),
'#description' => t('Default is %val', array('%val' => ($defaults['lazy_filter_loadInvisible']) ? 'checked' : 'unchecked')),
'#default_value' => variable_get('lazy_filter_image_fields', $defaults['lazy_filter_image_fields']),
'#return_value' => TRUE,
);
$form['settings']['lazy_filter_placeholderSrc'] = array( $form['settings']['lazy_filter_placeholderSrc'] = array(
'#type' => 'textfield', '#type' => 'textfield',
'#title' => t('Placeholder image URL'), '#title' => t('Placeholder image URL'),
'#description' => t('Default is %val', array('%val' => $defaults['lazy_filter_placeholderSrc'])), '#description' => t('Default is %val', array('%val' => $defaults['lazy_filter_placeholderSrc'])),
'#default_value' => variable_get('lazy_filter_placeholderSrc', $defaults['lazy_filter_placeholderSrc']), '#default_value' => variable_get('lazy_filter_placeholderSrc', $defaults['lazy_filter_placeholderSrc']),
'#size' => 100,
);
$form['paths'] = array(
'#type' => 'fieldset',
'#title' => t('Disabled pages'),
'#description' => t('<p>There could be pages Lazy-loading should be disabled; set them here.</p>'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['paths']['lazy_disabled_paths'] = array(
'#type' => 'textarea',
'#title' => t('Lazy-loading is disabled for both <em>image fields</em> and <em>inline images/iframes</em> in content on following pages'),
'#default_value' => variable_get('lazy_disabled_paths', $defaults['lazy_disabled_paths']),
'#description' => t('Specify pages by using their paths. Enter one path per line.'),
); );
$form['blazy'] = array( $form['blazy'] = array(
...@@ -128,6 +131,15 @@ function lazy_configuration_form($form, $form_state) { ...@@ -128,6 +131,15 @@ function lazy_configuration_form($form, $form_state) {
'#value' => t('Save configuration'), '#value' => t('Save configuration'),
); );
// Notify the user if the library is not available, and disable the form.
$library_installed = variable_get('lazy_library_installed');
if (!$library_installed) {
drupal_set_message(t('The bLazy library could not be found.'), 'warning');
drupal_set_message(t('Follow the instructions in the README.md file or in the <a href="!url">help</a> page for installing the bLazy library.', array('!url' => url('admin/help/lazy'))), 'status');
$form['submit']['#attributes']['disabled'] = TRUE;
}
return $form; return $form;
} }
...@@ -151,7 +163,10 @@ function lazy_configuration_form_submit($form, &$form_state) { ...@@ -151,7 +163,10 @@ function lazy_configuration_form_submit($form, &$form_state) {
$value = intval($value); $value = intval($value);
} }
if (in_array($key, $bool_value)) { if (in_array($key, $bool_value)) {
$value = boolval($value); $value = !!$value;
}
if ('string' === gettype($value)) {
$value = trim($value);
} }
variable_set($key, $value); variable_set($key, $value);
} }
......
name = Lazy-load name = Lazy-load
description = "This module integrates bLazy script to lazy load inline images and/or iframes via input-filters." description = "This module integrates bLazy script via image field display formatters and input-filters for inline images and iframes."
core = 7.x core = 7.x
dependencies[] = drupal:filter dependencies[] = drupal:filter
dependencies[] = libraries dependencies[] = libraries
......
...@@ -21,7 +21,7 @@ function lazy_install() { ...@@ -21,7 +21,7 @@ function lazy_install() {
'lazy_filter_successClass' => 'b-loaded', 'lazy_filter_successClass' => 'b-loaded',
'lazy_filter_validateDelay' => 25, 'lazy_filter_validateDelay' => 25,
'lazy_filter_placeholderSrc' => 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==', 'lazy_filter_placeholderSrc' => 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==',
'lazy_filter_image_fields' => FALSE, 'lazy_disabled_paths' => 'rss.xml',
); );
variable_set('lazy_filter_defaults', $defaults); variable_set('lazy_filter_defaults', $defaults);
...@@ -39,7 +39,7 @@ function lazy_enable() { ...@@ -39,7 +39,7 @@ function lazy_enable() {
'%filter' => 'Lazy-load', '%filter' => 'Lazy-load',
'!path' => url('admin/config/content/formats'), '!path' => url('admin/config/content/formats'),
); );
$message = t('The <a href="!config">Lazy</a> module was installed. The new %filter filter should be enabled in desired <a href="!path">text-formats</a>.', $options); $message = t('The <a href="!config">Lazy-load</a> module was installed. The new %filter filter should be enabled in desired <a href="!path">text-formats</a>.', $options);
drupal_set_message($message, 'warning'); drupal_set_message($message, 'warning');
} }
...@@ -60,6 +60,8 @@ function lazy_uninstall() { ...@@ -60,6 +60,8 @@ function lazy_uninstall() {
variable_del('lazy_filter_validateDelay'); variable_del('lazy_filter_validateDelay');
variable_del('lazy_filter_placeholderSrc'); variable_del('lazy_filter_placeholderSrc');
variable_del('lazy_filter_image_fields'); variable_del('lazy_filter_image_fields');
variable_del('lazy_library_installed');
variable_del('lazy_disabled_paths');
$module = 'lazy'; $module = 'lazy';
$name = 'lazy_filter'; $name = 'lazy_filter';
...@@ -67,6 +69,42 @@ function lazy_uninstall() { ...@@ -67,6 +69,42 @@ function lazy_uninstall() {
->condition('module', $module) ->condition('module', $module)
->condition('name', $name) ->condition('name', $name)
->execute(); ->execute();
// Revert image field formatters back to `image`.
$lazy_enabled_fields = array();
$field_map = field_info_field_map();
$i = 1;
$max_messages = 10;
foreach ($field_map as $field_name => $field) {
if ($field['type'] === 'image') {
foreach ($field['bundles'] as $entity_type => $bundle) {
$field_instance = field_info_instance($entity_type, $field_name, $bundle[0]);
foreach ($field_instance['display'] as $display_name => $display) {
if ($field_instance['display'][$display_name]['module'] === 'lazy') {
$field_instance['display'][$display_name]['type'] = 'image';
$field_instance['display'][$display_name]['module'] = 'image';
field_update_instance($field_instance);
if ($i <= $max_messages) {
drupal_set_message(t('The %label (<code>!field_name</code>) field in %bundle (!entity_type) type is reverted back in the %display display mode.', array(
'%label' => $field_instance['label'],
'!field_name' => $field_instance['field_name'],
'%bundle' => $field_instance['bundle'],
'!entity_type' => $field_instance['entity_type'],
'%display' => $display_name,
)),
'warning',
TRUE
);
}
$i++;
}
}
}
}
}
if ($i > $max_messages) {
drupal_set_message(t('Also reverted back %no other image fields.', array('%no' => $i - $max_messages)));
}
} }
/** /**
...@@ -90,6 +128,8 @@ function lazy_requirements($phase) { ...@@ -90,6 +128,8 @@ function lazy_requirements($phase) {
$requirements['blazy']['description'] = $blazy['error message']; $requirements['blazy']['description'] = $blazy['error message'];
$requirements['blazy']['severity'] = REQUIREMENT_ERROR; $requirements['blazy']['severity'] = REQUIREMENT_ERROR;
} }
variable_set('lazy_library_installed', $blazy['installed']);
} }
return $requirements; return $requirements;
...@@ -127,3 +167,46 @@ function lazy_update_7100() { ...@@ -127,3 +167,46 @@ function lazy_update_7100() {
variable_set('lazy_filter_defaults', $defaults); variable_set('lazy_filter_defaults', $defaults);
variable_set('lazy_filter_image_fields', $defaults['lazy_filter_image_fields']); variable_set('lazy_filter_image_fields', $defaults['lazy_filter_image_fields']);
} }
/**
* Disable module, if bLazy library is not installed yet.
*/
function lazy_update_7101() {
$blazy = libraries_detect('blazy');
variable_set('lazy_library_installed', $blazy['installed']);
}
/**
* New configuration option to set which pages should disable Lazy-loading.
*/
function lazy_update_7102() {
$defaults = variable_get('lazy_filter_defaults');
$defaults['lazy_disabled_paths'] = 'rss.xml';
variable_set('lazy_filter_defaults', $defaults);
variable_set('lazy_disabled_paths', $defaults['lazy_disabled_paths']);
}
/**
* Image fields now use display formatter to enable lazy-loading per field.
*/
function lazy_update_7103() {
$image_fields = variable_get('lazy_filter_image_fields');
if ($image_fields) {
$field_map = field_info_field_map();
foreach ($field_map as $field_name => $field) {
if ($field['type'] === 'image') {
foreach ($field['bundles'] as $entity_type => $bundle) {
$field_instance = field_info_instance($entity_type, $field_name, $bundle[0]);
foreach ($field_instance['display'] as $display_name => $display) {
if ($field_instance['display'][$display_name]['type'] === 'image') {
$field_instance['display'][$display_name]['type'] = 'lazy';
$field_instance['display'][$display_name]['module'] = 'lazy';
field_update_instance($field_instance);
}
}
}
}
}
}
variable_del('lazy_filter_image_fields');
}
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
Drupal.behaviors.lazy = { Drupal.behaviors.lazy = {
attach: function (context, settings) { attach: function (context, settings) {
var options = settings.lazy.bLazy ? settings.lazy.bLazy : {}; var options = settings.lazy ? settings.lazy : {};
new Blazy(options); Drupal.lazy = new Blazy(options);
} }
}; };
......
This diff is collapsed.