Image captions through tinymce

Permalink 1 user found helpful
I wonder if anyone has a solution they'd like to share for this: managing image captions in the tinymce editor.

I know I could create a custom template with the image block and grab the alt/caption, but that's not an ideal option in this case (more work for the client).

I'm looking to create an image coupled to a caption that then could be floated left or right anywhere in a content block. Seems that this would have to be a tinymce plugin or snippet/template. I've done some digging around and am not really any closer to a solution.

Any tips on how to implement this? Seems like such a basic function yet is proving to be a bear to implement!

kirkroberts
 
jbx replied on at Permalink Best Answer Reply
jbx
I think I would use a class as a trigger for this, along with the image title as the source. So your client would set the image title in the File Manager to whatever they want their caption to be. Then, in tinyMCE, they would add a class to the image (maybe .caption or similar) to indicate that they want to add a caption to that image.

You can then choose between php post processing and jQuery post processing to select all images with that class and add the caption and format accordingly. jQuery would probably be slightly easier, but php would be more robust...

Jon
kirkroberts replied on at Permalink Reply
kirkroberts
Cool, thanks for the reply and ideas, jbx!

jQuery seems pretty clear: find every img with .caption and do some stuff.

Going the PHP route is a little more mysterious to me, so I'm curious. Broadly speaking, how would you do that? Would it need to be a custom template for the Content block that handles the processing? String searches/replacements/additions? Sorry if this is a big question... any pointers would be greatly appreciated!

EDIT: by the way, I think this a really elegant solution (far better than anything I had come up with) and will set about using the jQuery method... but would also love to hear about the basics of the PHP method if you're willing to share.
jbx replied on at Permalink Reply
jbx
Yeah, custom template for the content box was what I was thinking - or just override the view.

Going from the top of my head, you would need some kind of a regular expression to extract all the image tags containing 'class="caption"' and then do something like
$html = '<div>' . $img . '<br />' . $title . '</div>';


Then do a preg_replace using your original expression to find the image tags again and replace them with your new code.

That's roughly the lines I was thinking along...

Jon
kirkroberts replied on at Permalink Reply
kirkroberts
Awesome.
I was about to say that using the DOM with jQuery seemed way more doable (for me), but then I ran across this html parser for PHP:http://simplehtmldom.sourceforge.net/...

I'd rather do this server-side if possible so I'm going to give it a spin later this week. Thanks, Jon!
kirkroberts replied on at Permalink Reply
kirkroberts
This technique totally worked for me, thanks!

I updated my custom tinymce settings with a class for img tags ("captioned") so the user can toggle that on/off.

Then copied /concrete/blocks/content/view.php to /blocks/content/view.php and added simple_html_dom.php to /blocks/content (fromhttp://simplehtmldom.sourceforge.net/... ).

In view.php I used this code:
defined('C5_EXECUTE') or die("Access Denied.");
   $content = $controller->getContent();
   include_once('simple_html_dom.php');
   $html = str_get_html($content);
   foreach($html->find('img.captioned') as $e) {
      if (isset($e->title)) {
         $imgClasses = $e->class;
         $divClasses = 'captioned-img';
         // move classes from img to containing div
         $testClasses = array('left', 'right');
         foreach($testClasses as $class) {
            if (strpos($imgClasses, $class) !== false) {
               $divClasses .= ' ' . $class;
               $imgClasses = str_replace($class, '', $imgClasses);
               $e->class = $imgClasses;


The user sets the caption in the tinymce image editor ("title" field).

With the addition of the proper styles to the stylesheet we have captions in the Content block! Woohoo!

Hope that helps someone! Thanks again, Jon!
michaelfm replied on at Permalink Reply
michaelfm
Very helpful :) I tried different approaches before. This is just great and furthermore convenient for editors! Thank you guys!
twomoons replied on at Permalink Reply
twomoons
Hi kirkroberts, this is exactly what have been looking for! But I am lost on very first step. How do I custom tinymce setting please?
kirkroberts replied on at Permalink Reply
kirkroberts
twomoons... here's a link to the thread where I learned about creating settings in tinymce:http://www.concrete5.org/community/forums/customizing_c5/tinymce-cu...
Either click the "view best answer" link or find the comment from abberdab. Be prepared to have your tinymce mind blown.
growlrooed replied on at Permalink Reply
growlrooed
Hi Kirk,
This solution is pretty damn cool. The only problem I am having with it is trying to figure out how to pull the width of the image into the being the width of the container div.

Any idea what PHP hook would pull the image width style into the div?

Thanks,
Ed
kirkroberts replied on at Permalink Reply
kirkroberts
Chances are good you'll want to set your width on your container via CSS and have the image inside be max-width: 100%; and height: auto !important;

Or you could get the dimensions of the image using PHP and getimagesize:http://www.php.net/manual/en/function.getimagesize.php...
growlrooed replied on at Permalink Reply
growlrooed
Thanks Kirk!

Yes I have to figure out a way to make this as seamless as possible for my client.
It figures that out of all the great features of Concrete5 they managed to focus on the one flaw with image captions that doesn't even come close to how wordpress can easily place them into an image.

You are right though about the CSS solution. I might go back into the editor and make a custom container class for a <p> element and use that to hold the images. This will allow for more customizing of the caption. Like if the client wants to put links in it.

Note to C5 team: You gonna let wordpress top C5? No!
kirkroberts replied on at Permalink Reply
kirkroberts
I have to admit I haven't had a need to use this solution in quite a while, but that's mostly because I build completely custom sites.

It DOES seem like something that should be readily available, particularly since the 900-lb gorilla (Wordpress) has it***. I think the c5 people might say that it's really a TinyMCE thing, or that you could always use a custom block (I don't think the default Image block even lets you have a caption).

I have used a custom paragraph style for captions, but that really only works if you're not floating your images, and it puts a burden on the site editor.

The solution in this thread works quite well, but it still takes a bit of fiddling to get it set up. If I had more need for it maybe a plug-n-play custom block template would be in order. And unfortunately the site editor doesn't see the caption in the TinyMCE editor.

*** EDIT: this solution originally came about because I was building a site for a person that was used to Wordpress and she threw down the gauntlet of "Wordpress can do that". After hearing that I knew I had to find a way!
kirkroberts replied on at Permalink Reply
kirkroberts
Doing a quick search of the forums for "image captions" it seems like NO ONE else is asking for this feature, so we're probably on our own with this one.

Seems odd to me... I'd think more people would be interested in this as a standard feature. Or maybe it's just that if it were there it would get used a lot, but people are making do without it.

EDIT: can't believe this solution is 3+ years old and there still isn't a better way to do this.
growlrooed replied on at Permalink Reply
growlrooed
Yes Kirk It does blow my mind since captions on photos is so crucial in most news sites or on...any site.

After extended testing, I couldn't get that php work around to completely do what I wanted, nor was it intuitive enough for a client to understand.

I ended up altering tinymce's stylesheet to include a paragraph styles that acts as a holder for the photo and caption. Still not the best solution.

I know that one of the developers, Franz, lives here in Portland. Maybe I'll ask him if I could meet with him to see if there's a way to create this in the next version.

There is definitely a wider need for it than between you and I.
kirkroberts replied on at Permalink Reply
kirkroberts
At one point I heard the c5 people wanted to move toward using Redactor instead of TinyMCE. Not sure what the status is on that now, or if that would offer any more options on this topic.

If you want a better way to do this the best best will probably be a TinyMCE plugin. Here's a link to one that I just found with a quick web search:https://github.com/manojlds/tinymce-image-caption...
No idea if it works well, or at all.

CMSes are funny. Getting a good handle on the CMS itself is one thing, but if you really want to shine as a developer that delivers editor-friendly sites you have to learn a lot about how the WYSIWYG editor works and can be configured.
jordanlev replied on at Permalink Reply
jordanlev
I'm surprised nobody has mentioned Designer Content yet:
http://www.concrete5.org/marketplace/addons/designer-content...
(coincidentally enough programmed by me, and the awesome icon designed by Kirk).

For the sites I build, I try to keep as much "structured content" out of TinyMCE as possible because it is such a clunky interface for most users. Designer Content will let you create your own custom block (for example, an image with a caption) so it can have the exact markup around each element that you as the designer want, without the user needing to do anything special. It will also give you the exact image sizes if you need them.

As with any tool, it does not solve every problem perfectly. In this case, I can see how it might not be ideal if what you're after is allowing the user to insert images anywhere and everywhere inline within their textual content -- because the custom blocks you would make with Designer Content would need to be separate elements on the page (because they'd be added as new blocks, separate from the "content" block). But honestly I have never had a situation where my users wanted to add arbitrary numbers of photos inline with their textual content -- it's always been that my page type designs will have pre-designated areas for photos (e.g. 1 or 2 big ones at the top, a few in the sidebar, or scattered in between sections of text... not inline with it though). So your mileage may vary.

-Jordan
growlrooed replied on at Permalink Reply
growlrooed
Hi Jordan,
Your Designer Content is a great block that is of huge use in any Concrete5 build. (which reminds me I need to send you PP bucks as thanks for doing such a great job.)

Anyhow, I did created these Designer Content blocks with defined image areas. But one can never anticipate all client needs. Of course despite my careful construction and template design, they invariably asked me if it was possible to place captioned images elsewhere in the content. Ergo, the conundrum.

I actually tried that PHP hack on one of the blocks made with Designer Content. It almost worked perfectly - except for the fact that it wasn't intuitive enough for clients who have no experience with coding/multi-step stylings.
jordanlev replied on at Permalink Reply
jordanlev
Check out the "Content Around Image" block --http://www.concrete5.org/marketplace/addons/content-around-image/...
kirkroberts replied on at Permalink Reply
kirkroberts
Thanks for the tips.
@madhattertcm: I haven't jumped on the html5 ship yet, but it's good to know about that.
@jordanlev: I appreciate the effort but I'm hoping to create something that will be easier for the client. I want to (as much as possible) take away the question of what block to use, or having to cut up portions of content into different blocks (otherwise I'd just use a custom view on an Image block to show the alt text and be done). With the classname/post-processing option the client can add as many image/caption pairs as wanted into one Content block. At least theoretically :-) This is the way I'm already handling floating images left/right (with the styles drop-down) so it will be an easy extension of that.
alanski replied on at Permalink Reply
alanski
Somewhat late posting to the party....
this is a brilliant solution - had it working in 10 minutes.

Just got make the core image block responsive now with overrides.

Thanks for the example here