The Project
I’m working on a plugin to resize and embed rows of images using shortcodes that will be converted into <img>
tags. In most cases there will be multiple images per row, and the rows are separated by line breaks. Here’s a simplified example of what 4 rows might look like in the text editor…
[img id="311409" w="1200" h="800"][img id="287556" w="900" h="750"] [img id="511289" w="600" h="800"][img id="839905" w="850" h="850"][img id="214342" w="1150" h="1800"][img id="973537" w="450" h="300"] [img id="223798" w="1600" h="900"] [img id="592297" w="750" h="900"][img id="896732" w="800" h="600"][img id="722292" w="900" h="1100"]
The width and height shortcode attributes are the original dimensions of each image, not the display sizes. The plugin automatically resizes them (smaller) so that each image in the row is the same height and all the images in the row together fit the width of the page exactly. (This math is the easy part that I already have working.)
The Problem
When WordPress comes across the first image shortcode in a row, it’s expected that it will be replace by a real <img>
tag at that point, but I don’t yet know at what size it’s supposed to be displayed. There is also no built-in way for the shortcode parser to know when it has reached a line-break.
I need to know how many image shortcodes are on a given line (in the “row”) and use all of their dimensions together to calculate the desired size of each image before I’m ready to replace the first shortcode in the row. As far as I’ve been able to tell, WordPress can only deal with each shortcode one at a time in the order they are found, and there doesn’t seem to be an easy way to tell where the line breaks fall.
Solution?
Am I overlooking an easy solution? An ideal one would…
- Leave the images easily separable — using one tag per image so I can easily reorder them by dragging and dropping between rows, or even between posts (plus, as I mentioned in a comment below, my actual shortcodes are much more complex than my example and would be extremely unwieldy if combined into one tag per row)
- Use WordPress’ built-in shortcode support — since that’s the preferred method for plugins to embed content, and WordPress has nice parsing tools already built-in for that purpose
- Not require “parent” tags for each row of images — to keep the code simple and flexible for future development
- Remain as future-proof as possible — e.g. if I wrote my own complex regex for this and overloaded
do_shortcode()
then there’s a greater chance that this could break in the future as WordPress evolves
Compromise…
After several hours of research I haven’t been able to find anything that would meet all these criteria. If I have to compromise on these points, I would start from the bottom of that list. For example…
- Rolling my own
do_shortcode()
and/or modifying the (very complex) regex pattern (defined inget_shortcode_regex()
) — these are the kinds of creative solutions that I am most interested in - Using parent tags to encapsulate each row, e.g.
[imgrow][img ...][img ...][/imgrow]
— though that doesn’t really answer the question as asked - Abandoning the shortcode tools altogether, e.g. implementing a broader custom filter using
add_filter()
— which technically maintains the shortcode syntax but gives up all the nice tools (and at that point the answer to this question would simply be “it’s not currently possible”)
1 Answer
I think it is easier to introduce the shortcode [imgs]
that could be used like this:
[imgs id="12,13,14" w="200,300,400" h="300,400,500"]
[imgs id="19,20" w="50,60" h="80,100"]
then you can explode each attribute with respect to comma (,) and loop over corresponding array.