Take the tour ×

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.


Am I overlooking an easy solution? An ideal one would...

  1. 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)
  2. 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
  3. Not require "parent" tags for each row of images -- to keep the code simple and flexible for future development
  4. 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


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...

  1. Rolling my own do_shortcode() and/or modifying the (very complex) regex pattern (defined in get_shortcode_regex()) -- these are the kinds of creative solutions that I am most interested in
  2. Using parent tags to encapsulate each row, e.g. [imgrow][img ...][img ...][/imgrow] -- though that doesn't really answer the question as asked
  3. 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")
share|improve this question
add comment

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.

share|improve this answer
I've considered this, and while it would technically solve the issue, it makes the rows very inflexible. For my application I occasionally need to be able to drag-drop reorder the images between rows, and this would make that impossible. Also, I used simplified shortcodes in my example -- they actually have seven attributes, one of which (caption) is often quite long. Combining three, four, or even more images in one shortcode like this would become very unwieldy. But thanks for the suggestion! –  Austin Feb 10 at 19:40
ok, but what about this kind of structure: [imgrow][img][img]...[/imgrow] ? –  birgire Feb 10 at 21:20
Thanks again, birgire -- I've just clarified the question a bit. A nested tag structure wouldn't be ideal for my purposes, but I might consider it a passable "second-best" alternative. It would still present challenges to implement. Wordpress would jump into the [imgrow] shortcode, and I could pull out the [img] tags with $content, but I would still have to manually parse that string of tags to fetch the attributes and compute sizes before I could dump them recursively back into do_shortcode(). Does that make sense? Might be best to move this idea to a separate answer... –  Austin Feb 10 at 21:33
Some grid jQuery plugins (like Masonry: masonry.desandro.com) do this kind of image fitting you describe in your question, so maybe you could simplify your project by moving some part to jQuery? So you wouldn't need to do the fitting in php - just another idea ;-) –  birgire Feb 11 at 1:14
another idea would be to use [imgs id="12,23,34,45"] with only the id attribute and then add a metabox with more detailed info in json/xml/csv/shortcode format, for example : id,w,h \n 12,200,300 \n 23,400,600 (but maybe your drag/drop idea rules this out?) –  birgire Feb 11 at 1:31
show 2 more comments

Your Answer


