✦ v1.0.1 · stable

Mosaico —
Gallery & Slider

A WordPress plugin for building advanced image and video galleries using a custom post type. Supports masonry and square grids, Swiper slider, GLightbox lightbox, dynamic category filtering, AJAX load more, lazy loading, drag-and-drop reordering, and video support. No page builder required.

Author · Mohammad Parvez
Version · 1.0.1
Requires · WordPress 6.0+
No ACF needed · built-in CPT

Overview

Everything the plugin does at a glance.

🖼

Gallery grid

Masonry or square 1:1 grid with hover overlays, category badges, video badges, and optional titles.

🎠

Swiper slider

Standalone touchscreen-ready slider with autoplay, loop, captions, and per-instance configuration.

🔍

GLightbox

Click any item to open a full-screen lightbox with prev/next navigation, keyboard support, and video playback.

🏷

Dynamic filtering

Filter buttons auto-generated from item categories. Hidden when no categories are set.

AJAX load more

Paginate large galleries without a page reload. Lazy loading re-initialises automatically for new items.

🎬

Video support

Add an MP4 URL to any item. Shows thumbnail + play icon in the grid; plays in GLightbox on click.

  • Custom Post Type mgs_gallery — create as many galleries as you need, no ACF required
  • Built-in admin meta box with drag-and-drop reordering of gallery items
  • Per-gallery shortcodes with post_id — display different galleries on different pages
  • Two shortcodes: [mgs_gallery] for the grid and [mgs_gallery_slider] for a standalone slider
  • Responsive at 4 / 2 / 1 columns (desktop / tablet / mobile)
  • Assets loaded via CDN (Swiper 11, GLightbox) — no build step required
  • WordPress nonce protection on all AJAX requests
  • Shortcode reference column in the WordPress admin post list — copy shortcodes in one click
  • Separated CSS and JS files for easy customisation

Requirements

Requirement Minimum Notes
WordPress 6.0+ Uses register_post_meta, wp_json_encode
PHP 7.4+ Uses null coalescing ??, arrow functions
ACF / Plugins None The plugin registers its own CPT and meta — no third-party plugins needed
jQuery Any Bundled with WordPress core — used for admin drag-and-drop and AJAX

Installation

Upload the plugin folder

Go to Plugins → Add New → Upload Plugin, choose the zipped plugin folder, then click Install Now. Or FTP the folder directly to wp-content/plugins/mosaico-gallery-slider/.

Activate the plugin

Click Activate Plugin. A new Galleries menu item (photo icon) will appear in the WordPress admin sidebar.

Create a Gallery post

Go to Galleries → Add New. Give it a title, then scroll to the Gallery Items meta box. Click Add Item to add images, titles, categories, and optional video URLs.

Copy the shortcode

Go to Galleries list view. In the Shortcode column next to your gallery, select the shortcode type from the dropdown and click Copy.

Paste into a page

Edit any page or post, paste the shortcode into the content, and publish. Your gallery will appear on the front end.

Quick start

The fastest path from zero to a working gallery.

Show all galleries, masonry layout

[mgs_gallery]

Show one specific gallery, square grid

[mgs_gallery post_id="42" grid="square"]

Standalone slider only

[mgs_gallery_slider post_id="42"]
💡
To find a gallery's post_id, go to Galleries in the admin, hover over any gallery title, and look at the URL in the status bar — the number after post= is the ID. Or use the Shortcode column — it prefills the correct post_id for you.

[mgs_gallery_slider]

A fully standalone Swiper slider. No grid, no filter bar, no load-more button. Drop it anywhere — a page, post, or alongside a [mgs_gallery] shortcode. Multiple instances on the same page each get a unique ID so they never interfere with each other.

Attributes

Attribute Type Default Options / Range Description
post_id integer 0 any post ID ID of the gallery post to pull slides from. When 0, items from all published gallery posts are merged.
per_view integer 4 1 – any Max slides visible at once on desktop (≥992 px). Automatically capped on smaller screens: 3 on ≥768 px, 2 on ≥576 px, 1 on mobile.
height integer (px) 200 min 80 Slide image height in pixels. Images are cropped with object-fit:cover so all slides share the same height regardless of original dimensions.
autoplay string yes yes · no Auto-advance slides at the interval set by delay. Pauses when the user interacts with the slider.
delay integer (ms) 3500 min 500 Milliseconds between autoplay advances. Only used when autoplay="yes".
loop string yes yes · no Loop back to the first slide after the last one.
speed integer (ms) 500 min 100 Slide transition animation duration in milliseconds.
show_title string yes yes · no Show the item title as a gradient caption overlay at the bottom of each slide. Hidden when the title field is empty.

Examples

// Simplest usage — slider for one gallery, all defaults
[mgs_gallery_slider post_id="42"]

// Taller slides, slower autoplay
[mgs_gallery_slider post_id="42" height="360" delay="5000"]

// 3 slides wide, no autoplay, no loop, no titles
[mgs_gallery_slider post_id="42" per_view="3" autoplay="no" loop="no" show_title="no"]

// Single full-width slide, hero style
[mgs_gallery_slider post_id="99" height="480" per_view="1" delay="6000"]

// Fast transition, no autoplay, 2 slides wide
[mgs_gallery_slider post_id="42" per_view="2" autoplay="no" speed="250"]
💡
Multiple [mgs_gallery_slider] shortcodes on the same page are fully independent — each gets a unique auto-incremented ID (dg-slider-1, dg-slider-2, …) so they never conflict.

Gallery post type

The plugin registers a custom post type mgs_gallery labelled Galleries in the admin. It appears in the sidebar with a photo icon.

  • Supports: title and featured image
  • Public: true — galleries are individually accessible on the front end if needed
  • REST API: show_in_rest: true — compatible with the block editor
  • Capabilities: standard post capabilities — any user who can edit posts can manage galleries

Meta box fields

The Gallery Items meta box appears on every Gallery edit screen. Each row is one gallery item.

Field Type Required Description
Image WP Media required Click the upload area or drag an image. The plugin stores the attachment ID and URLs for full, large, and medium sizes. The large size is shown in the grid; medium is used in the Swiper strip.
Title / Caption text optional Shown below the image in masonry mode, as an overlay in square mode, and as a caption in the slider. Also used as the lightbox heading and image alt text fallback.
Category text optional Free-text category tag. Items sharing the same category get a shared filter button. Leave blank to exclude the item from filtering. Matching is case-insensitive.
Video URL URL optional Direct URL to an MP4 file. When set, the grid item shows the image thumbnail with a play icon overlay and VIDEO badge. Clicking opens the video in GLightbox. If no image is set, a native <video> element is rendered inline instead.

Drag-and-drop reordering

Grab the ⠿ handle on the left side of any item row and drag it to a new position. The order is saved when you publish or update the post.

Add / Remove items

Click + Add Item in the footer bar to append a new row with a slide-in animation. Click the button on any row to remove it. Both actions update the item count in the header instantly.

Shortcode column

The Galleries list view has a Shortcode column next to every gallery title. It provides a dropdown of ready-made shortcode variants for that gallery's post_id:

Dropdown option Shortcode generated
Default Gallery [mgs_gallery post_id="…"]
Square Grid [mgs_gallery post_id="…" grid="square"]
Without Titles [mgs_gallery post_id="…" show_title="no"]
With Swiper Strip [mgs_gallery post_id="…" swiper="yes"]
3 Columns [mgs_gallery post_id="…" columns="3"]
2 Columns [mgs_gallery post_id="…" columns="2"]
Fixed Height [mgs_gallery post_id="…" height="300"]
Slider [mgs_gallery_slider post_id="…"]
Slider No Titles [mgs_gallery_slider post_id="…" show_title="no"]
3-col Slider [mgs_gallery_slider post_id="…" per_view="3"]
Slider No Autoplay [mgs_gallery_slider post_id="…" autoplay="no"]

Select a variant, then click Copy — the shortcode is copied to your clipboard.

Grid modes

Masonry default

Uses CSS columns to create a Pinterest-style layout. Images retain their natural aspect ratio. The column count responds to screen size:

Viewport Columns
≥ 992 px (desktop) 4
577–992 px (tablet) 2
≤ 576 px (mobile) 1

Square

Uses CSS display:grid with aspect-ratio:1/1 per cell. Every image is cropped with object-fit:cover to fill the square. The item title, when visible, appears as a semi-transparent bar along the bottom of each tile. Column breakpoints are the same as masonry.

[mgs_gallery grid="masonry"]   // natural heights, Pinterest-style
[mgs_gallery grid="square"]    // uniform 1:1 tiles

Custom columns

The default column count is 4 on desktop. Use the columns attribute to override this for both masonry and square modes. The value is automatically capped at 2 on tablet and 1 on mobile regardless of what you set.

[mgs_gallery columns="3"]   // 3 columns desktop, 2 tablet, 1 mobile
[mgs_gallery columns="2"]   // 2 columns desktop, 2 tablet, 1 mobile
[mgs_gallery columns="1"]   // single column — full width items

Filter bar

The filter bar appears automatically above the grid whenever at least one gallery item has a non-empty Category field. It is hidden entirely when no categories are set.

  • Buttons are generated from all unique category values across the displayed items
  • Clicking a category shows only matching items — no page reload
  • Clicking All restores the full grid
  • Filtering is scoped to its own grid — multiple galleries on one page filter independently
  • Matching is case-insensitive: Nature and nature are the same category
The filter only hides/shows items already in the DOM. Items loaded via Load More also respect the active filter once appended.

Load more (AJAX)

When the total gallery items exceed the per_page value, a Load More button appears below the grid. On click it:

  • Sends an authenticated AJAX request (nonce-verified) to admin-ajax.php
  • Fetches the next batch of rendered item HTML from the server
  • Appends the new items to the grid
  • Re-initialises lazy loading for the newly added images
  • Hides the button automatically once all items are loaded

Changing items per page

// Show 4 items initially, load 4 more on each click
[mgs_gallery post_id="42" per_page="4"]

Lazy loading

Grid images use a two-layer lazy loading strategy:

  • Each image is initially a 1×1 transparent GIF placeholder; the real URL is stored in data-src
  • A JavaScript IntersectionObserver (with a 100px root margin) swaps in the real URL as the image enters the viewport
  • A CSS opacity 0 → 1 fade plays once the image has fully loaded
  • Browsers without IntersectionObserver support fall back to immediate loading
  • Lazy loading is re-initialised automatically after each Load More batch

The standalone slider uses the native loading="lazy" attribute directly on slide images.

Video support

Any gallery item can have a video by entering a direct MP4 URL in the Video URL field of the meta box.

In the gallery grid

  • With image + video: shows the image thumbnail with a circular play icon overlay and a red VIDEO badge. Clicking opens the video in GLightbox.
  • Video only (no image): renders a native <video> element inline with playback controls.

In the slider

  • With image + video: shows the thumbnail with a play button overlay. Clicking opens GLightbox with the video playing.
  • Video only (no image): renders a native <video> element in the slide.
GLightbox uses source: 'local' for direct MP4 files. YouTube and Vimeo embeds are not supported — host the file on your own server or a CDN and use the direct file URL.

Full examples

A — Portfolio page, square grid

[mgs_gallery
  post_id="23"
  grid="square"
  per_page="12"
]

A2 — 3-column grid, fixed height

[mgs_gallery
  post_id="23"
  grid="masonry"
  columns="3"
  height="280"
  per_page="9"
]

B — Homepage hero slider

[mgs_gallery_slider
  post_id="5"
  height="480"
  per_view="1"
  delay="6000"
  show_title="yes"
]

C — Gallery grid + slider on same page

// Grid at the top
[mgs_gallery post_id="55" grid="masonry"]

// Slider strip further down the same page
[mgs_gallery_slider post_id="55" height="160" per_view="4"]

D — Two sliders, different galleries

[mgs_gallery_slider post_id="23" height="220" autoplay="yes"]

[mgs_gallery_slider post_id="47" height="220" autoplay="no" loop="no"]

E — Gallery with all options

[mgs_gallery
  post_id="99"
  grid="square"
  per_page="8"
  show_title="yes"
  swiper="yes"
]

Changelog

v1.0.1 current

  • Separated CSS into assets/css/admin.css and assets/css/gallery.css
  • Separated JS into assets/js/admin.js and assets/js/gallery.js
  • Refactored monolithic class into includes/ files: CPT, MetaBox, Helpers, Shortcodes, Ajax, Assets, AdminColumns
  • Removed Bootstrap 5 dependency — replaced with custom CSS
  • Video items in [mgs_gallery]: show thumbnail + play icon overlay; video plays in GLightbox on click
  • Video items in [mgs_gallery_slider]: same thumbnail + play icon behaviour, consistent with gallery grid
  • GLightbox source: 'local' applied for direct MP4 files
  • Added show_title attribute to both shortcodes
  • Admin shortcode column updated with all current shortcode variants
  • Added columns attribute to [mgs_gallery] — override desktop column count (1–6)
  • Added height attribute to [mgs_gallery] — fixed pixel height per item with object-fit:cover
  • Added width attribute to [mgs_gallery] — fixed pixel width per item

v1.0.0

  • Initial release
  • Custom Post Type mgs_gallery with built-in meta box — no ACF required
  • Drag-and-drop item reordering in the admin meta box
  • [mgs_gallery] shortcode with masonry / square grid, filter bar, load more, lazy load, and lightbox
  • [mgs_gallery_slider] standalone Swiper slider shortcode
  • GLightbox integration for full-screen image and video viewing
  • AJAX load more with nonce protection
  • Shortcode reference column in Galleries admin list

Let's Make Great Things Together

I'd love to hear about your project. Drop me a message or reach out directly at hello@webdevparvez.com

Available for new projects
Email
hello@webdevparvez.com
Phone / WhatsApp
+880 1717 127738
Location
Bangladesh — Remote Worldwide