PHP /**
* Snippet Name: Easy Image Gallery
* Snippet Author: coding-bunny.com
* Description: Register CPT for image galleries with visual selector, flexible layouts, and shortcode display.
* Version: 1.0.0
*
* USAGE EXAMPLES:
*
* Basic usage (show a gallery by its ID):
* [custom_gallery id="123"]
*
* Grid layout with 4 columns, 1:1 thumbs, large images, with lightbox and overlay:
* [custom_gallery id="123" layout="grid" columns="4" thumb_ratio="1:1" size="large" lightbox="true" overlay="true"]
*
* Justified layout, row height 200px, medium images, no overlay:
* [custom_gallery id="123" layout="justified" rowheight="200" size="medium" overlay="false"]
*
* AVAILABLE PARAMETERS:
* - id: ID of the gallery post (required)
* - layout: Gallery layout: 'grid' or 'justified' (default: 'grid')
* - columns: Number of columns (for grid layout, default: 3, min: 1, max: 6)
* - size: Image size: 'thumbnail', 'medium', 'large', 'full' (default: 'large')
* - lightbox: Enable lightbox popup on click (true/false, default: true)
* - overlay: Show hover overlay effect (true/false, default: true)
* - showtitle: Show image title on hover (true/false, default: false)
* - thumb_ratio: Thumbnail aspect ratio for grid: 'original', '1:1', '2:3', '3:2', '4:3', '3:4' (default: 'original')
* - rowheight: Row height for justified layout (default: 220)
* - margins: Margin (gap) between images in px (default: 8)
* - borderradius: Border radius for images in px (default: 0)
*
*/
if ( ! defined ( ' ABSPATH ' ) ) exit;
add_action ( ' init ' , function () {
register_post_type ( ' cbscg_gallery ' , [
' labels ' => [
' name ' => __ ( ' Image Gallery ' , ' cbscg ' ),
' singular_name ' => __ ( ' Gallery ' , ' cbscg ' ),
' add_new_item ' => __ ( ' Add New Gallery ' , ' cbscg ' ),
' edit_item ' => __ ( ' Edit Gallery ' , ' cbscg ' ),
' view_item ' => __ ( ' View Gallery ' , ' cbscg ' ),
' all_items ' => __ ( ' All Galleries ' , ' cbscg ' ),
],
' public ' => true ,
' has_archive ' => true ,
' rewrite ' => [ ' slug ' => ' galleries ' ],
' menu_icon ' => ' dashicons-format-gallery ' ,
' supports ' => [ ' title ' ],
' show_in_rest ' => true ,
' capability_type ' => ' post ' ,
]) ;
}) ;
add_action ( ' add_meta_boxes ' , function () {
add_meta_box (
' cbscg_gallery_images ' ,
__ ( ' Gallery Images & Settings ' , ' cbscg ' ),
function ( $ post ) {
wp_nonce_field ( ' cbscg_save_gallery ' , ' cbscg_gallery_nonce ' ) ;
$ image_ids = get_post_meta ( $ post -> ID , ' _cbscg_image_ids ' , true ) ;
$ image_ids = is_array ( $ image_ids ) ? array_map ( ' absint ' , $ image_ids ) : array_filter ( array_map ( ' absint ' , explode ( ' , ' , ( string ) $ image_ids ))) ;
$ columns = absint ( get_post_meta ( $ post -> ID , ' _cbscg_columns ' , true )) ?: 3 ;
$ layout = sanitize_key ( get_post_meta ( $ post -> ID , ' _cbscg_layout ' , true )) ?: ' grid ' ;
$ size = sanitize_key ( get_post_meta ( $ post -> ID , ' _cbscg_size ' , true )) ?: ' large ' ;
$ lightbox = get_post_meta ( $ post -> ID , ' _cbscg_lightbox ' , true ) ;
$ lightbox = ( $ lightbox === '' || $ lightbox ) ? ' true ' : ' false ' ;
$ overlay = get_post_meta ( $ post -> ID , ' _cbscg_overlay ' , true ) ;
$ overlay = ( $ overlay === '' || $ overlay ) ? ' true ' : ' false ' ;
$ showtitle = get_post_meta ( $ post -> ID , ' _cbscg_showtitle ' , true ) ;
$ showtitle = ( $ showtitle === '' || $ showtitle ) ? ' true ' : ' false ' ;
$ thumb_ratio = sanitize_text_field ( get_post_meta ( $ post -> ID , ' _cbscg_thumb_ratio ' , true )) ?: ' original ' ;
$ rowheight = absint ( get_post_meta ( $ post -> ID , ' _cbscg_rowheight ' , true )) ?: 220 ;
$ margins = absint ( get_post_meta ( $ post -> ID , ' _cbscg_margins ' , true )) ?: 8 ;
$ borderradius = absint ( get_post_meta ( $ post -> ID , ' _cbscg_borderradius ' , true )) ?: 0 ;
?>
< input type = " hidden " id = " cbscg-gallery-ids " name = " cbscg_gallery_ids " value = " <?php echo esc_attr(implode(',', $ image_ids )); ?> " >
< button type = " button " class= " button " id = " cbscg-select-images " ><? php _e ( ' Select Images ' , ' cbscg ' ) ; ?></ button >
< ul id = " cbscg-preview " >
<? php foreach ( $ image_ids as $ id ) : ?>
< li data - id = " <?php echo esc_attr( $ id ); ?> " >
<? php echo wp_kses_post ( wp_get_attachment_image ( $ id , ' thumbnail ' )) ; ?>
</ li >
<? php endforeach; ?>
</ ul >
< hr >
< table class= " form-table " style = " margin-top:1em; " >
< tr >
< th >< label for= " cbscg_layout " ><? php _e ( ' Layout ' , ' cbscg ' ) ; ?></ label ></ th >
< td >
< select name = " cbscg_layout " id = " cbscg_layout " >
< option value = " grid " <? php selected ( $ layout , ' grid ' ) ; ?>> Grid </ option >
< option value = " justified " <? php selected ( $ layout , ' justified ' ) ; ?>> Justified </ option >
</ select >
</ td >
</ tr >
< tr id = " cbscg_columns_row " >
< th >< label for= " cbscg_columns " ><? php _e ( ' Columns ' , ' cbscg ' ) ; ?></ label ></ th >
< td >
< select name = " cbscg_columns " id = " cbscg_columns " >
<? php for ( $ i = 1 ;$ i <= 6 ;$ i ++ ) echo " <option value= \" $ i \" " . selected ( $ columns , $ i , false ) . " > $ i </option> " ; ?>
</ select >
</ td >
</ tr >
< tr id = " cbscg_thumb_ratio_row " >
< th >< label for= " cbscg_thumb_ratio " ><? php _e ( ' Thumb Ratio ' , ' cbscg ' ) ; ?></ label ></ th >
< td >
< select name = " cbscg_thumb_ratio " id = " cbscg_thumb_ratio " >
< option value = " original " <? php selected ( $ thumb_ratio , ' original ' ) ; ?>> Original </ option >
< option value = " 1:1 " <? php selected ( $ thumb_ratio , ' 1:1 ' ) ; ?>> 1 : 1 </ option >
< option value = " 2:3 " <? php selected ( $ thumb_ratio , ' 2:3 ' ) ; ?>> 2 : 3 </ option >
< option value = " 3:2 " <? php selected ( $ thumb_ratio , ' 3:2 ' ) ; ?>> 3 : 2 </ option >
< option value = " 4:3 " <? php selected ( $ thumb_ratio , ' 4:3 ' ) ; ?>> 4 : 3 </ option >
< option value = " 3:4 " <? php selected ( $ thumb_ratio , ' 3:4 ' ) ; ?>> 3 : 4 </ option >
</ select >
</ td >
</ tr >
< tr id = " cbscg_rowheight_row " >
< th >< label for= " cbscg_rowheight " ><? php _e ( ' Justified Row Height ' , ' cbscg ' ) ; ?></ label ></ th >
< td >
< input type = " number " name = " cbscg_rowheight " id = " cbscg_rowheight " value = " <?php echo esc_attr( $ rowheight ); ?> " style = " width:60px; " > px
</ td >
</ tr >
< tr id = " cbscg_margins_row " >
< th >< label for= " cbscg_margins " ><? php _e ( ' Gallery Margins ' , ' cbscg ' ) ; ?></ label ></ th >
< td >
< input type = " number " name = " cbscg_margins " id = " cbscg_margins " value = " <?php echo esc_attr( $ margins ); ?> " style = " width:60px; " > px
</ td >
</ tr >
< tr >
< th >< label for= " cbscg_borderradius " ><? php _e ( ' Border Radius ' , ' cbscg ' ) ; ?></ label ></ th >
< td >
< input type = " number " name = " cbscg_borderradius " id = " cbscg_borderradius " min = " 0 " max = " 50 " value = " <?php echo esc_attr( $ borderradius ); ?> " style = " width:60px; " > px
</ td >
</ tr >
< tr >
< th >< label for= " cbscg_size " ><? php _e ( ' Image Size ' , ' cbscg ' ) ; ?></ label ></ th >
< td >
< select name = " cbscg_size " id = " cbscg_size " >
< option value = " thumbnail " <? php selected ( $ size , ' thumbnail ' ) ; ?>> Thumbnail </ option >
< option value = " medium " <? php selected ( $ size , ' medium ' ) ; ?>> Medium </ option >
< option value = " large " <? php selected ( $ size , ' large ' ) ; ?>> Large </ option >
< option value = " full " <? php selected ( $ size , ' full ' ) ; ?>> Full </ option >
</ select >
</ td >
</ tr >
< tr >
< th >< label for= " cbscg_lightbox " ><? php _e ( ' Lightbox ' , ' cbscg ' ) ; ?></ label ></ th >
< td >
< input type = " checkbox " name = " cbscg_lightbox " id = " cbscg_lightbox " value = " 1 " <? php checked ( $ lightbox , ' true ' ) ; ?>>
</ td >
</ tr >
< tr >
< th >< label for= " cbscg_overlay " ><? php _e ( ' Overlay hover effect ' , ' cbscg ' ) ; ?></ label ></ th >
< td >
< input type = " checkbox " name = " cbscg_overlay " id = " cbscg_overlay " value = " 1 " <? php checked ( $ overlay , ' true ' ) ; ?>>
</ td >
</ tr >
< tr >
< th >< label for= " cbscg_showtitle " ><? php _e ( ' Show Image Title ' , ' cbscg ' ) ; ?></ label ></ th >
< td >
< input type = " checkbox " name = " cbscg_showtitle " id = " cbscg_showtitle " value = " 1 " <? php checked ( $ showtitle , ' true ' ) ; ?>>
</ td >
</ tr >
</ table >
< hr >
< label style = " font-weight:bold; " ><? php _e ( ' Shortcode ready to copy: ' , ' cbscg ' ) ; ?></ label >
< input type = " text " id = " cbscg-shortcode-display " readonly style = " width:99%;font-family:monospace;background:#f7f7f7;border:1px solid #e5e5e5; " onclick = " this.select() " >
< script >
function cbscg_generate_shortcode () {
var id = " <?php echo intval( $ post -> ID ); ?> " ;
var columns = document . getElementById ( ' cbscg_columns ' ) . value ;
var layout = document . getElementById ( ' cbscg_layout ' ) . value ;
var size = document . getElementById ( ' cbscg_size ' ) . value ;
var lightbox = document . getElementById ( ' cbscg_lightbox ' ) . checked ? " true " : " false " ;
var overlay = document . getElementById ( ' cbscg_overlay ' ) . checked ? " true " : " false " ;
var showtitle = document . getElementById ( ' cbscg_showtitle ' ) . checked ? " true " : " false " ;
var thumb_ratio = document . getElementById ( ' cbscg_thumb_ratio ' ) . value ;
var rowheight = document . getElementById ( ' cbscg_rowheight ' ) . value ;
var margins = document . getElementById ( ' cbscg_margins ' ) . value ;
var borderradius = document . getElementById ( ' cbscg_borderradius ' ) . value ;
var sc = ' [custom_gallery id=" ' + id + ' " layout=" ' + layout + ' " size=" ' + size + ' " lightbox=" ' + lightbox + ' " overlay=" ' + overlay + ' " showtitle=" ' + showtitle + ' " borderradius=" ' + borderradius + ' " ' ;
if ( layout === ' grid ' ) {
sc += ' columns=" ' + columns + ' " thumb_ratio=" ' + thumb_ratio + ' " margins=" ' + margins + ' " ' ;
}
if ( layout === ' justified ' ) {
sc += ' rowheight=" ' + rowheight + ' " margins=" ' + margins + ' " ' ;
}
sc += ' ] ' ;
document . getElementById ( ' cbscg-shortcode-display ' ) . value = sc ;
}
function cbscg_toggle_fields () {
var layout = document . getElementById ( ' cbscg_layout ' ) . value ;
if ( layout === ' grid ' ) {
document . getElementById ( ' cbscg_columns_row ' ) . style . display = '' ;
document . getElementById ( ' cbscg_thumb_ratio_row ' ) . style . display = '' ;
document . getElementById ( ' cbscg_rowheight_row ' ) . style . display = ' none ' ;
document . getElementById ( ' cbscg_margins_row ' ) . style . display = '' ;
} else {
document . getElementById ( ' cbscg_columns_row ' ) . style . display = ' none ' ;
document . getElementById ( ' cbscg_thumb_ratio_row ' ) . style . display = ' none ' ;
document . getElementById ( ' cbscg_rowheight_row ' ) . style . display = '' ;
document . getElementById ( ' cbscg_margins_row ' ) . style . display = '' ;
}
}
jQuery ( function ( $ ){
cbscg_toggle_fields () ;
cbscg_generate_shortcode () ;
$ ( ' #cbscg_columns,#cbscg_layout,#cbscg_size,#cbscg_lightbox,#cbscg_overlay,#cbscg_showtitle,#cbscg_thumb_ratio,#cbscg_rowheight,#cbscg_margins,#cbscg_borderradius ' ) . on ( ' change input ' , function () {
cbscg_toggle_fields () ;
cbscg_generate_shortcode () ;
}) ;
}) ;
</ script >
< style >
#cbscg-preview { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; cursor: move; }
#cbscg-preview li { list-style: none; border: 1px solid #ccc; border-radius: 4px; }
#cbscg-preview li img { max-width: 100px; max-height: 100px; }
#cbscg-preview li.selected { outline: 2px solid #007cba; }
</ style >
< script >
jQuery ( document ) . ready ( function ( $ ) {
let frame ;
$ ( ' #cbscg-select-images ' ) . on ( ' click ' , function ( e ) {
e . preventDefault () ;
let selected_ids = $ ( ' #cbscg-gallery-ids ' ) . val ()
? $ ( ' #cbscg-gallery-ids ' ) . val () . split ( ' , ' ) . map ( id => parseInt ( id )) . filter ( id => id )
: [] ;
if ( ! frame ) {
frame = wp . media ({
multiple: true ,
title: ' <?php echo esc_js(__( ' Select Images ' , ' cbscg ' )); ?> ' ,
library: { type : ' image ' }
}) ;
}
frame . on ( ' open ' , function () {
let selection = frame . state () . get ( ' selection ' ) ;
selection . reset () ;
if ( selected_ids . length > 0 ) {
selected_ids . forEach ( function ( id ) {
let attachment = wp . media . attachment ( id ) ;
attachment . fetch () ;
selection . add ( attachment ? attachment : null ) ;
}) ;
}
}) ;
frame . off ( ' select ' ) ;
frame . on ( ' select ' , function () {
const selection = frame . state () . get ( ' selection ' ) ;
const ids = selection . map ( att => att . id ) ;
$ ( ' #cbscg-gallery-ids ' ) . val ( ids . join ( ' , ' )) ;
$ ( ' #cbscg-preview ' ) . empty () ;
selection . each ( att => {
const thumb = att . attributes . sizes ? . thumbnail ? . url || att . attributes . icon ;
$ ( ' #cbscg-preview ' ) . append ( ` <li data-id="${att.id}"><img src=" ${ thumb } " /></li> ` ) ;
}) ;
}) ;
frame . open () ;
}) ;
$ ( ' #cbscg-preview ' ) . on ( ' click ' , ' li ' , function ( e ){
if ( e . ctrlKey || e . metaKey ) {
$ ( this ) . toggleClass ( ' selected ' ) ;
} else if ( e . shiftKey ) {
var $ items = $ ( this ) . parent () . children () ;
var first = $ items . index ( $ ( this ) . parent () . find ( ' .selected ' ) . first ()) ;
var last = $ items . index ( this ) ;
$ items . removeClass ( ' selected ' ) ;
$ items . slice ( Math . min ( first , last ), Math . max ( first , last ) + 1 ) . addClass ( ' selected ' ) ;
} else {
$ ( this ) . addClass ( ' selected ' ) . siblings () . removeClass ( ' selected ' ) ;
}
}) ;
$ ( document ) . on ( ' keydown ' , function ( e ) {
if (( e . key === " Delete " || e . key === " Backspace " ) && $ ( ' #cbscg-preview li.selected ' ) . length ) {
$ ( ' #cbscg-preview li.selected ' ) . remove () ;
updateIds () ;
}
}) ;
$ ( ' #cbscg-preview ' ) . on ( ' dblclick ' , ' li.selected ' , function () {
$ ( this ) . remove () ;
updateIds () ;
}) ;
$ ( ' #cbscg-preview ' ) . sortable ({
update: updateIds
}) ;
function updateIds () {
const newOrder = $ ( ' #cbscg-preview ' ) . children () . map ( function () {
return $ ( this ) . data ( ' id ' ) ;
}) . get () ;
$ ( ' #cbscg-gallery-ids ' ) . val ( newOrder . join ( ' , ' )) ;
}
}) ;
</ script >
<? php
} ,
' cbscg_gallery ' ,
' normal ' ,
' high '
) ;
}) ;
add_action ( ' save_post_cbscg_gallery ' , function ( $ post_id ) {
if ( ( defined ( ' DOING_AUTOSAVE ' ) && DOING_AUTOSAVE ) || !isset ( $ _POST [ ' cbscg_gallery_nonce ' ]) ) return;
if ( ! wp_verify_nonce ( $ _POST [ ' cbscg_gallery_nonce ' ], ' cbscg_save_gallery ' ) ) return;
if ( ! current_user_can ( ' edit_post ' , $ post_id ) ) return;
if ( isset ( $ _POST [ ' cbscg_gallery_ids ' ]) ) {
$ ids = array_filter ( array_map ( ' absint ' , explode ( ' , ' , sanitize_text_field ( $ _POST [ ' cbscg_gallery_ids ' ])))) ;
update_post_meta ( $ post_id , ' _cbscg_image_ids ' , $ ids ) ;
}
update_post_meta ( $ post_id , ' _cbscg_columns ' , isset ( $ _POST [ ' cbscg_columns ' ]) ? absint ( $ _POST [ ' cbscg_columns ' ]) : 3 ) ;
update_post_meta ( $ post_id , ' _cbscg_layout ' , isset ( $ _POST [ ' cbscg_layout ' ]) ? sanitize_key ( $ _POST [ ' cbscg_layout ' ]) : ' grid ' ) ;
update_post_meta ( $ post_id , ' _cbscg_size ' , isset ( $ _POST [ ' cbscg_size ' ]) ? sanitize_key ( $ _POST [ ' cbscg_size ' ]) : ' large ' ) ;
update_post_meta ( $ post_id , ' _cbscg_lightbox ' , !empty ( $ _POST [ ' cbscg_lightbox ' ]) ? 1 : 0 ) ;
update_post_meta ( $ post_id , ' _cbscg_overlay ' , !empty ( $ _POST [ ' cbscg_overlay ' ]) ? 1 : 0 ) ;
update_post_meta ( $ post_id , ' _cbscg_showtitle ' , !empty ( $ _POST [ ' cbscg_showtitle ' ]) ? 1 : 0 ) ;
update_post_meta ( $ post_id , ' _cbscg_thumb_ratio ' , isset ( $ _POST [ ' cbscg_thumb_ratio ' ]) ? sanitize_text_field ( $ _POST [ ' cbscg_thumb_ratio ' ]) : ' original ' ) ;
update_post_meta ( $ post_id , ' _cbscg_rowheight ' , isset ( $ _POST [ ' cbscg_rowheight ' ]) ? absint ( $ _POST [ ' cbscg_rowheight ' ]) : 220 ) ;
update_post_meta ( $ post_id , ' _cbscg_margins ' , isset ( $ _POST [ ' cbscg_margins ' ]) ? absint ( $ _POST [ ' cbscg_margins ' ]) : 8 ) ;
update_post_meta ( $ post_id , ' _cbscg_borderradius ' , isset ( $ _POST [ ' cbscg_borderradius ' ]) ? absint ( $ _POST [ ' cbscg_borderradius ' ]) : 0 ) ;
}) ;
add_filter ( ' manage_cbscg_gallery_posts_columns ' , function ( $ columns ) {
$ columns [ ' cbscg_shortcode ' ] = __ ( ' Shortcode ' , ' cbscg ' ) ;
return $ columns ;
}) ;
add_action ( ' manage_cbscg_gallery_posts_custom_column ' , function ( $ column , $ post_id ) {
if ( $ column === ' cbscg_shortcode ' ) {
$ columns = absint ( get_post_meta ( $ post_id , ' _cbscg_columns ' , true )) ?: 3 ;
$ layout = sanitize_key ( get_post_meta ( $ post_id , ' _cbscg_layout ' , true )) ?: ' grid ' ;
$ size = sanitize_key ( get_post_meta ( $ post_id , ' _cbscg_size ' , true )) ?: ' large ' ;
$ lightbox = get_post_meta ( $ post_id , ' _cbscg_lightbox ' , true ) ;
$ lightbox = ( $ lightbox === '' || $ lightbox ) ? ' true ' : ' false ' ;
$ overlay = get_post_meta ( $ post_id , ' _cbscg_overlay ' , true ) ;
$ overlay = ( $ overlay === '' || $ overlay ) ? ' true ' : ' false ' ;
$ showtitle = get_post_meta ( $ post_id , ' _cbscg_showtitle ' , true ) ;
$ showtitle = ( $ showtitle === '' || $ showtitle ) ? ' true ' : ' false ' ;
$ thumb_ratio = sanitize_text_field ( get_post_meta ( $ post_id , ' _cbscg_thumb_ratio ' , true )) ?: ' original ' ;
$ rowheight = absint ( get_post_meta ( $ post_id , ' _cbscg_rowheight ' , true )) ?: 220 ;
$ margins = absint ( get_post_meta ( $ post_id , ' _cbscg_margins ' , true )) ?: 8 ;
$ borderradius = absint ( get_post_meta ( $ post_id , ' _cbscg_borderradius ' , true )) ?: 0 ;
$ shortcode = ' [custom_gallery id=" ' . absint ( $ post_id ) . ' " layout=" ' . esc_attr ( $ layout ) . ' " size=" ' . esc_attr ( $ size ) . ' " lightbox=" ' . esc_attr ( $ lightbox ) . ' " overlay=" ' . esc_attr ( $ overlay ) . ' " showtitle=" ' . esc_attr ( $ showtitle ) . ' " borderradius=" ' . esc_attr ( $ borderradius ) . ' " ' ;
if ( $ layout === ' grid ' ) {
$ shortcode .= ' columns=" ' . esc_attr ( $ columns ) . ' " thumb_ratio=" ' . esc_attr ( $ thumb_ratio ) . ' " margins=" ' . esc_attr ( $ margins ) . ' " ' ;
}
if ( $ layout === ' justified ' ) {
$ shortcode .= ' rowheight=" ' . esc_attr ( $ rowheight ) . ' " margins=" ' . esc_attr ( $ margins ) . ' " ' ;
}
$ shortcode .= ' ] ' ;
printf (
' <input type="text" readonly value="%s" style="width:99%%;font-family:monospace;background:#f7f7f7;border:1px solid #e5e5e5;" onclick="this.select()"> ' ,
esc_attr ( $ shortcode )
) ;
}
}, 10 , 2 ) ;
add_action ( ' wp_footer ' , function () {
?>
< link rel = " stylesheet " href = " https://cdn.jsdelivr.net/npm/justifiedGallery@3.8.1/dist/css/justifiedGallery.min.css " crossorigin = " anonymous " referrerpolicy = " no-referrer " >
< style >
. cbscg - lightbox {
position: fixed ; inset : 0 ;
background: rgba ( 0 , 0 , 0 , 0 . 85 ) ;
display: none ;
justify - content : center ;
align - items : center ;
z - index : 9999 ;
}
. cbscg - lightbox [ aria - hidden = " false " ] { display : flex ; }
. cbscg - lightbox img {
max - width : 90 vw ;
max - height : 90 vh ;
border - radius : 6 px ;
box - shadow : 0 0 20 px #0008;
}
. cbscg - lightbox . cbscg - lightbox - close {
position: absolute ;
top: 24 px ; right : 24 px ;
background: none ; border : none ; color : #fff;
font - size : 2 rem ; cursor : pointer ; z - index : 10001 ;
}
</ style >
< div class= " cbscg-lightbox " aria - modal = " true " aria - hidden = " true " tabindex = " -1 " role = " dialog " >
< button class= " cbscg-lightbox-close " aria - label = " Close " > × </ button >
< img src = "" alt = "" >
</ div >
< script src = " https://code.jquery.com/jquery-3.7.1.min.js " crossorigin = " anonymous " referrerpolicy = " no-referrer " ></ script >
< script src = " https://cdn.jsdelivr.net/npm/justifiedGallery@3.8.1/dist/js/jquery.justifiedGallery.min.js " crossorigin = " anonymous " referrerpolicy = " no-referrer " ></ script >
< script >
document . addEventListener ( ' DOMContentLoaded ' , function () {
if ( window . _cbscgLightboxLoaded ) return;
window . _cbscgLightboxLoaded = true;
const overlay = document . querySelector ( ' .cbscg-lightbox ' ) ;
const img = overlay . querySelector ( ' img ' ) ;
const closeBtn = overlay . querySelector ( ' .cbscg-lightbox-close ' ) ;
let lastTrigger = null;
document . body . addEventListener ( ' click ' , function ( e ) {
const link = e . target . closest ( ' .cbscg-lightbox-link ' ) ;
if ( link ) {
e . preventDefault () ;
img . src = link . getAttribute ( ' href ' ) ;
img . alt = link . querySelector ( ' img ' ) ? . alt || '' ;
overlay . setAttribute ( ' aria-hidden ' , ' false ' ) ;
overlay . focus () ;
lastTrigger = link ;
}
}) ;
function closeLightbox () {
overlay . setAttribute ( ' aria-hidden ' , ' true ' ) ;
img . src = '' ;
if ( lastTrigger ) { lastTrigger . focus () ; }
}
overlay . addEventListener ( ' click ' , function ( e ) {
if ( e . target === overlay ) closeLightbox () ;
}) ;
closeBtn . addEventListener ( ' click ' , closeLightbox ) ;
document . addEventListener ( ' keydown ' , function ( e ) {
if ( overlay . getAttribute ( ' aria-hidden ' ) === ' false ' && ( e . key === ' Escape ' || e . key === ' Esc ' )) {
closeLightbox () ;
}
}) ;
}) ;
</ script >
<? php
} , 5 ) ;
add_shortcode ( ' custom_gallery ' , function ( $ atts ) {
static $ count = 0 ;
$ count ++;
$ defaults = [
' id ' => 0 ,
' layout ' => ' grid ' ,
' columns ' => 3 ,
' size ' => ' large ' ,
' lightbox ' => ' true ' ,
' overlay ' => ' true ' ,
' rowheight ' => 220 ,
' margins ' => 8 ,
' showtitle ' => ' false ' ,
' thumb_ratio ' => ' original ' ,
' borderradius ' => 0 ,
] ;
$ atts = shortcode_atts ( $ defaults , $ atts , ' custom_gallery ' ) ;
$ gallery_id = absint ( $ atts [ ' id ' ]) ;
$ layout = in_array ( $ atts [ ' layout ' ], [ ' grid ' , ' justified ' ], true ) ? $ atts [ ' layout ' ] : ' grid ' ;
$ columns = max ( 1 , min ( 6 , absint ( $ atts [ ' columns ' ]))) ;
$ size = in_array ( $ atts [ ' size ' ], [ ' thumbnail ' , ' medium ' , ' large ' , ' full ' ], true ) ? $ atts [ ' size ' ] : ' large ' ;
$ lightbox = filter_var ( $ atts [ ' lightbox ' ], FILTER_VALIDATE_BOOLEAN ) ;
$ overlay = filter_var ( $ atts [ ' overlay ' ], FILTER_VALIDATE_BOOLEAN ) ;
$ rowheight = absint ( $ atts [ ' rowheight ' ]) ;
$ margins = absint ( $ atts [ ' margins ' ]) ;
$ showtitle = filter_var ( $ atts [ ' showtitle ' ], FILTER_VALIDATE_BOOLEAN ) ;
$ thumb_ratio = strtolower ( trim ( $ atts [ ' thumb_ratio ' ])) ;
$ unique_id = ' cbscg-gallery- ' . $ count ;
$ borderradius = absint ( $ atts [ ' borderradius ' ]) ;
$ ratio_map = [
' 1:1 ' => [ 1 , 1 ],
' 2:3 ' => [ 2 , 3 ],
' 3:2 ' => [ 3 , 2 ],
' 4:3 ' => [ 4 , 3 ],
' 3:4 ' => [ 3 , 4 ],
] ;
$ thumb_ratio_clean = str_replace ( ' ' , '' , $ thumb_ratio ) ;
$ padding_pct = '' ;
if ( $ layout === ' grid ' && $ thumb_ratio_clean !== ' original ' && isset ( $ ratio_map [ $ thumb_ratio_clean ])) {
list ( $ w , $ h ) = $ ratio_map [ $ thumb_ratio_clean ] ;
$ padding_pct = ( floatval ( $ h ) / floatval ( $ w )) * 100 . ' % ' ;
}
$ ids = get_post_meta ( $ gallery_id , ' _cbscg_image_ids ' , true ) ;
$ ids = is_array ( $ ids ) ? array_map ( ' absint ' , $ ids ) : array_filter ( array_map ( ' absint ' , explode ( ' , ' , ( string ) $ ids ))) ;
if ( empty ( $ ids )) {
return ' <p> ' . esc_html__ ( ' No images found in gallery. ' , ' cbscg ' ) . ' </p> ' ;
}
if ( $ layout === ' justified ' ) {
add_action ( ' wp_footer ' , function () use ( $ unique_id , $ rowheight , $ margins , $ overlay , $ lightbox , $ showtitle , $ borderradius ) {
?>
< script >
jQuery ( function ( $ ){
$ ( ' #<?php echo esc_js($unique_id); ?> ' ) . justifiedGallery ({
rowHeight: <? php echo ( int ) $ rowheight ; ?> ,
margins : <? php echo ( int ) $ margins ; ?> ,
captions : <? php echo $ showtitle ? ' true ' : ' false ' ; ?> ,
lastRow : ' justify '
}) ;
}) ;
</ script >
< style >
. jg - caption {
display:none ! important ;
}
#<?php echo esc_attr($unique_id); ?> a img {
border - radius : <? php echo ( int ) $ borderradius ; ?> px ;
box - shadow : 0 1 px 6 px #0001;
<? php if ( $ lightbox ) : ?> cursor : zoom - in ;<? php endif; ?>
transition : filter 0 . 3 s ;
display : block ;
width : 100 %;
height: auto ;
}
<? php if ( $ overlay ) : ?>
#<?php echo esc_attr($unique_id); ?> a : hover img ,
#<?php echo esc_attr($unique_id); ?> a : focus img {
filter: brightness ( 50 % ) ;
}
<? php endif; ?>
<? php if ( $ showtitle ) : ?>
#<?php echo esc_attr($unique_id); ?> . caption {
background: none ! important ;
color: #fff !important;
font - size : 1 . 2 em ! important ;
font - weight : bold ! important ;
text - align : center ! important ;
white - space : pre - line ! important ;
left: 50 % ! important ;
top: 50 % ! important ;
transform: translate ( - 50 % , - 50 % ) ! important ;
position: absolute ! important ;
width: max - content ! important ;
min - width : 40 % ! important ;
max - width : 90 % ! important ;
opacity: 0 ;
pointer - events : none ;
z - index : 2 ;
text - shadow : 0 0 6 px #000, 0 0 1px #000;
transition: opacity 0 . 2 s ;
}
#<?php echo esc_attr($unique_id); ?> a : hover . caption ,
#<?php echo esc_attr($unique_id); ?> a : focus . caption {
opacity: 1 ! important ;
}
<? php endif; ?>
</ style >
<? php
} , 20 ) ;
ob_start () ;
echo ' <div id=" ' . esc_attr ( $ unique_id ) . ' " class="cbscg-justified-gallery"> ' ;
foreach ( $ ids as $ id ) {
$ thumb = wp_get_attachment_image_url ( $ id , $ size ) ;
$ full = wp_get_attachment_image_url ( $ id , ' full ' ) ;
$ title = get_the_title ( $ id ) ;
if ( !$ thumb || !$ full ) continue;
$ title_attr = esc_attr ( $ title ) ;
$ img_tag = ' <img src=" ' . esc_url ( $ thumb ) . ' " alt=" ' . $ title_attr . ' " loading="lazy"> ' ;
echo ' <a href=" ' . esc_url ( $ full ) . ' " class="cbscg-lightbox-link" title=" ' . $ title_attr . ' "> ' ;
echo $ img_tag ;
if ( $ showtitle ) {
echo ' <div class="caption"> ' . esc_html ( $ title ) . ' </div> ' ;
}
echo ' </a> ' ;
}
echo ' </div> ' ;
return ob_get_clean () ;
} else {
add_action ( ' wp_footer ' , function () use ( $ columns , $ unique_id , $ overlay , $ lightbox , $ showtitle , $ thumb_ratio_clean , $ padding_pct , $ borderradius , $ margins ) {
?>
< style >
#<?php echo esc_attr($unique_id); ?> {
display: grid ;
gap: <? php echo ( int ) $ margins ; ?> px ;
grid - template - columns : repeat ( <? php echo esc_attr ( $ columns ) ; ?> , 1 fr) ;
width : 100 %;
}
#<?php echo esc_attr($unique_id); ?> . gallery - item img {
width: 100 %;
height: 100 %;
object- fit : cover ;
border - radius : <? php echo ( int ) $ borderradius ; ?> px ;
<? php if ( $ lightbox ) : ?> cursor : zoom - in ;<? php endif; ?>
box - shadow : 0 1 px 6 px #0001;
transition : filter 0 . 3 s ;
display : block ;
position : absolute ;
left: 0 ; top : 0 ;
}
. cbscg - thumb - wrap {
position: relative ;
width: 100 %;
<? php if ( $ thumb_ratio_clean !== ' original ' ) : ?>
height : 0 ;
padding - top : <? php echo $ padding_pct ; ?>;
<? php endif; ?>
overflow : hidden ;
}
<? php if ( $ thumb_ratio_clean === ' original ' ) : ?>
. cbscg - thumb - wrap img {
position: static;
height: auto ;
}
<? php endif; ?>
. cbscg - thumb - wrap img {
transition: filter 0 . 3 s ease ;
}
<? php if ( $ overlay ) : ?>
. cbscg - thumb - wrap : hover img ,
. cbscg - thumb - wrap : focus img {
filter: brightness ( 50 % ) ;
}
<? php endif; ?>
<? php if ( $ showtitle ) : ?>
. cbscg - title - center {
position: absolute ;
top: 50 %;
left: 50 %;
transform: translate ( - 50 % , - 50 % ) ;
color: #fff;
font - size : 1 . 2 em ;
font - weight : bold ;
text - align : center ;
white - space : pre - line ;
pointer - events : none ;
opacity: 0 ;
transition: opacity 0 . 2 s ;
z - index : 2 ;
text - shadow : 0 0 6 px #000, 0 0 1px #000;
}
. cbscg - thumb - wrap : hover . cbscg - title - center ,
. cbscg - thumb - wrap : focus . cbscg - title - center {
opacity: 1 ;
}
<? php endif; ?>
@ media ( max - width : 900 px ) {
#<?php echo esc_attr($unique_id); ?> {
grid - template - columns : repeat ( 2 , 1 fr ) ;
}
}
@ media ( max - width : 500 px ) {
#<?php echo esc_attr($unique_id); ?> {
grid - template - columns : 1 fr ;
}
}
</ style >
<? php
} , 20 ) ;
ob_start () ;
echo ' <div id=" ' . esc_attr ( $ unique_id ) . ' " class="cbscg-gallery layout-grid"> ' ;
foreach ( $ ids as $ id ) {
$ thumb = wp_get_attachment_image_url ( $ id , $ size ) ;
$ full = wp_get_attachment_image_url ( $ id , ' full ' ) ;
$ title = get_the_title ( $ id ) ;
if ( !$ thumb || !$ full ) continue;
$ title_attr = esc_attr ( $ title ) ;
echo ' <div class="gallery-item"> ' ;
if ( $ lightbox ) echo ' <a href=" ' . esc_url ( $ full ) . ' " class="cbscg-lightbox-link" tabindex="0" aria-label=" ' . $ title_attr . ' "> ' ;
echo ' <div class="cbscg-thumb-wrap"> ' ;
echo ' <img src=" ' . esc_url ( $ thumb ) . ' " loading="lazy" alt=" ' . $ title_attr . ' "> ' ;
if ( $ showtitle ) {
echo ' <span class="cbscg-title-center"> ' . esc_html ( $ title ) . ' </span> ' ;
}
echo ' </div> ' ;
if ( $ lightbox ) echo ' </a> ' ;
echo ' </div> ' ;
}
echo ' </div> ' ;
return ob_get_clean () ;
}
}) ;