8

I'm using Wygwam on a site, and I'm allowing content administrators to embed media (specifically, videos) within the main, body copy/content area.

Is there a way to automatically wrap the embedded content in some kind of custom HTML? It seems that the embeds are already automatically wrapped in a classless <div>, and I'd like to, at the very least, give that <div> some kind of class or ID, so that it'd be something like <div class="inline-media">.

3 Answers 3

8

You can do this without editing the Wygwam source. First you need to create a custom config file for CKEditor. Create a JavaScript file called something like 'ckeditor_config.js' and then set Wygwam to use it. You can do this by adding an advanced setting to your Wygwam editor configuration. Add the 'customConfig' setting and enter the path to the JavaScript file you just created. It will look like:

/javascripts/ckeditor_config.js

Then enter the following code into the file. It sets up a htmlFilter that adds the 'inline-media' class name to all div elements that contain an iframe.

CKEDITOR.on( 'instanceReady', function( ev ) {
    ev.editor.dataProcessor.htmlFilter.addRules({
        elements: {
            $: function (element) {
                // Add inline-media class name to embedded media
                if (element.name == 'div' && element.children[0].name == 'iframe') {
                    element.attributes.class = 'inline-media';
                    return element;
                }
            }
        }
    });
});

Later versions of Wygwam will strip out the div when you save the field. In your Wywam settings, add an advanced setting for 'extraAllowedContent' and set it to div(inline-media)

2
  • This approach works, and it's what I'll be using for this project. Thank you very much, Dylan.
    – ctrlaltdel
    Nov 19, 2013 at 15:14
  • Hey no problem! Glad to hear it works.
    – Dylan
    Nov 20, 2013 at 0:56
3

I believe to do so, you would need to create a Custom Style Set for Wygwam. See the Wygwam Docs over a Pixel & Tonic. Though, I recommend creating a class instead of an id. Since someone will most likely add more than one media embed sometime in the future.

Additionally, this StackExchange post deals with editing the Wygwam .js for custom sets.

2

EDIT: Please see the accepted answer above from Dylan as an approach for handling this type of functionality.


nonprofit_tech's suggestion to try using a custom style set does work, but it involves a two-step process: the content administrator must first add the custom wrapper from the style set dropdown, and then embed the media via the toolbar's media embed button. Again, this works, but places more of a burden on the administrator who may or may not be very tech savvy, and if you accidentally navigate outside of the empty wrapper element, you might not embed the media in the right place. Not an ideal solution, but here's a sample of the code that I wrote to test out that theory:

CKEDITOR.stylesSet.add('custom-styleset',[{
  name: 'Embed Wrapper',
  element: 'div',
  attributes: {'class': 'inline-media'}
}]);

Another solution to this is to edit the minified ckeditor.js, but this is not recommended by the folks at Pixel & Tonic, as this file would likely be overwritten by updating the plugin in the future.

However, if you really want to do this, you can add a line to that file to add a class to the element that wraps the embedded media. In the current build of the plugin, the code looks like this:

div=b.document.createElement("div");
div.setHtml(this.getContentElement("iframe","embedArea").getValue());

To which I added:

div.setAttribute("class","inline-media");

And the final code looked like:

div=b.document.createElement("div");
div.setAttribute("class","inline-media");
div.setHtml(this.getContentElement("iframe","embedArea").getValue());

Again, this is not recommended, as changes to this file will likely be overwritten if the plugin is updated in the future.

I think that a better solution to this issue will be to create my own embed button that replicates the functionality of the default embed button, but also wraps the embedded content in the markup that I need to have.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.