Developer Documentation
Extend Query Loop Masonry with WordPress hooks. Customize aspect ratios, limit position slots, and control masonry instances programmatically.
Quick Overview
Block Editor Filters
Customize the block editor experience using WordPress hooks.
- Client-friendly labels
- Filter aspect ratio options
- Limit position slots
Frontend API
Control running masonry instances via JavaScript.
- Trigger layout recalculation
- Handle AJAX content loading
- Access all running instances
Block Editor Filters
ph_qlm.aspectRatioOptions
JS Hook/Filter
Customize the aspect ratio dropdown options shown in the block editor sidebar.
Use Case: Replace generic ratios with client-friendly labels like “Product Image” or “Hero Banner”
Pro Tip: Use Image Dimensions
Don’t know the aspect ratio? Just use your image’s actual width and height!
Example: Image is 1200px × 800px → use value 1200/800
Important: Existing Blocks Behavior
Old values persist: Query Loops Blocks with Masonry with previously selected aspect ratios keep those values, even if removed from filter options.
Frontend continues working: CSS is generated with stored values regardless of current filter options.
Editor UI: Dropdown may appear blank if stored value doesn’t match any current option.
Values only change: When user manually selects a new option from the dropdown.
Plugin’s Default options for reference
Square (1:1)
Portrait (3:4)
Portrait (2:3)
Landscape (4:3)
Landscape (3:2)
Landscape (16:9)
Ultra Wide (21:9)
Option 1: JavaScript (Recommended)
Add this code to your existing block editor JavaScript file. If you already have a JS file enqueued via enqueue_block_editor_assets, use that.
my-theme/js/editor-customizations.js
wp.hooks.addFilter(
'ph_qlm.aspectRatioOptions',
'my-theme/ratios',
(options) => [
{ label: 'Hero Image', value: '5/3' },
{ label: 'Product Card', value: '4/5' },
{ label: 'Thumbnail', value: '1/1' }
]
);
Option 2: Create New JavaScript File
Don’t have a block editor JS file? Create one and enqueue it:
1. Create file in your theme:
my-theme/js/editor-customizations.js
wp.hooks.addFilter(
'ph_qlm.aspectRatioOptions',
'my-theme/ratios',
(options) => [
{ label: 'Hero Image', value: '5/3' },
{ label: 'Product Card', value: '4/5' },
{ label: 'Thumbnail', value: '1/1' }
]
);
2. Enqueue in functions.php:
my-theme/functions.php
function my_theme_enqueue_editor_assets() {
wp_enqueue_script(
'my-theme-editor-customizations',
get_template_directory_uri() . '/js/editor-customizations.js',
['wp-hooks', 'ph-qlm-editor-extensions'],
wp_get_theme()->get('Version'),
true
);
}
add_action(
'enqueue_block_editor_assets',
'my_theme_enqueue_editor_assets'
);
Option 3: PHP Only (Simple)
Quick approach using inline script. Less maintainable but works for simple customizations.
my-theme/functions.php
function my_custom_ratios() {
$script = "
wp.hooks.addFilter(
'ph_qlm.aspectRatioOptions',
'my-theme/ratios',
function(options) {
return [
{ label: 'Hero Image', value: '5/3' },
{ label: 'Product Card', value: '4/5' },
{ label: 'Thumbnail', value: '1/1' }
];
}
);
";
wp_add_inline_script(
'ph-qlm-editor-extensions',
$script,
'after'
);
}
add_action(
'enqueue_block_editor_assets',
'my_custom_ratios',
20
);
ph_qlm.maxPositions
JS Hook/Filter
Control the maximum number of selector position slots available in the editor.
Default: 6 positions (1st, 2nd, 3rd, 4th, 5th, 6th)
Why Limit or Extend number of Positions?
- Prevent client confusion with too few or too many options
- Hero layouts (first 3 posts only)
- Fixed pattern designs
- Simplified UI for content editors
Use Case: News site with hero layout – only first 3 posts need custom aspect ratios
Option 1: JavaScript (Recommended)
Add this code to your existing block editor JavaScript file. If you already have a JS file enqueued via enqueue_block_editor_assets, use that.
my-theme/js/editor-customizations.js
wp.hooks.addFilter(
'ph_qlm.maxPositions',
'my-theme/positions',
(max) => 3 // Limit to 3 position slots
);
Option 2: Create New JavaScript File
Don’t have a block editor JS file? Create one and enqueue it:
1. Create file in your theme:
my-theme/js/editor-customizations.js
wp.hooks.addFilter(
'ph_qlm.maxPositions',
'my-theme/positions',
(max) => 3
);
2. Enqueue in functions.php:
my-theme/functions.php
function my_theme_enqueue_editor_assets() {
wp_enqueue_script(
'my-theme-editor-customizations',
get_template_directory_uri() . '/js/editor-customizations.js',
['wp-hooks', 'ph-qlm-editor-extensions'],
wp_get_theme()->get('Version'),
true
);
}
add_action(
'enqueue_block_editor_assets',
'my_theme_enqueue_editor_assets'
);
Option 3: PHP Only (Simple)
Quick approach using inline script. Less maintainable but works for simple customizations.
my-theme/functions.php
function limit_positions() {
$script = "
wp.hooks.addFilter(
'ph_qlm.maxPositions',
'my-theme/positions',
function(max) {
return 3;
}
);
";
wp_add_inline_script(
'ph-qlm-editor-extensions',
$script,
'after'
);
}
add_action(
'enqueue_block_editor_assets',
'limit_positions',
20
);
Frontend API
Global API Object
Front-end JS
Access and control all running masonry instances via window.ph_qlm
version
Plugin version string
instances[]
Array of MasonryController instances
destroyAll()
Destroy all instances and cleanup
Note: API available after DOMContentLoaded event
Inspect API Structure
my-theme/js/theme.js
console.log(window.ph_qlm);
// Output:
{
version: '0.1.0',
instances: [/* MasonryController[] */],
destroyAll: Function
}
Individual Instance Control
my-theme/js/theme.js
// Access first instance
const instance = window.ph_qlm.instances[0];
// Destroy instance
instance.destroy();
// Get Masonry instance
const masonry = instance.getInstance();
Batch Operations
my-theme/js/theme.js
// Destroy everything
window.ph_qlm.destroyAll();
Real-World Examples
📸
Photography Portfolio
Custom aspect ratios for different photography styles
Requirements
- Hero shot in 5:3 ratio
- Portrait photos in 4:5
- Cinematic wide shots
- Square prints for Instagram
Replace generic options with photography-specific terminology
my-theme/js/editor-customizations.js
wp.hooks.addFilter(
'ph_qlm.aspectRatioOptions',
'photo-site/ratios',
(options) => [
{
label: 'Hero Shot (5:3)',
value: '5/3'
},
{
label: 'Portrait (4:5)',
value: '4/5'
},
{
label: 'Cinematic (2.35:1)',
value: '2.35/1'
},
{
label: 'Square Print',
value: '1/1'
}
]
);
📰
News Site Hero Layout
Fixed hero layout with limited slots
Layout Structure
- Position 1: Hero story (16:9)
- Position 2-3: Featured articles (4:3)
- Remaining: Standard posts
- Max 3 position slots needed
Limit positions to prevent unnecessary complexity
my-theme/js/editor-customizations.js
//Limit to 3 positions
wp.hooks.addFilter(
'ph_qlm.maxPositions',
'news-site/positions',
() => 3
);
// News-specific ratios
wp.hooks.addFilter(
'ph_qlm.aspectRatioOptions',
'news-site/ratios',
(options) => [
{
label: 'Hero Story',
value: '16/9'
},
{
label: 'Featured Article',
value: '4/3'
},
{
label: 'Standard Post',
value: '3/4'
}
]
);
⚡
AJAX Content Loading
Automatic detection with MutationObserver
No Manual Re-layout Required!
Masonry uses MutationObserver to automatically detect when posts are added or removed from the DOM. Your AJAX implementations will work automatically without any extra code.
Works Automatically With
- Load more buttons
- Infinite scroll
- WordPress Query Loop pagination
- Filter/search results
- Any dynamic content updates
How It Works
The plugin watches the masonry container for changes. When .wp-block-post elements are added or removed, masonry automatically re-calculates the layout.
Manual Control: The API is still available for edge cases where you need explicit control over layout timing.
Automatic (Recommended)
(Example of how your AJAX code might look like)
my-theme/js/ajax-handler.js
// Just update the DOM - masonry handles the rest!
fetch('/api/posts')
.then(response => response.json())
.then(data => {
// Update DOM
updatePostsDOM(data);
// That's it! MutationObserver handles re-layout
});
// Load more button - no manual layoutAll() needed
loadMoreBtn.addEventListener('click', async () => {
const newPosts = await fetchPosts();
container.append(newPosts);
// Masonry automatically detects new posts
});
Manual Control (Edge Cases)
For rare cases where you need explicit timing control
my-theme/js/theme.js
// Force immediate re-layout
window.ph_qlm.layoutAll();
// Or control specific instance
window.ph_qlm.instances[0].layout();
Technical Reference
Breakpoints
Mobile
0-599px
Small
600-781px
Medium
782-959px
Large
960-1279px
Wide
1280-1439px
Huge
1440px+
Default Settings
Max Positions:
6
Column Range:
1-16 columns
Default Columns:
3
Mode Options:
every, only
Target Block:
core/post-template
Made by an Expert WordPress Developer

Hi! My name is Adam Husar and as a solo developer, I truly value your interest in this plugin and your support. I’m a senior Full-Stack WordPress and WooCommerce developer with over 10 years of experience working on projects for small to enterprise companies across Europe and the US.
I’ve created this plugin for everyone to use and enjoy, and I strive to constantly improve it. If you have any ideas for new features or encounter any issues, please don’t hesitate to reach out to me at adam@wpqueryloopmasonry.com.
Your feedback helps make this plugin better for everyone!
Adam Husar / Pixel Hero