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

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)

| improve this answer | |
  • This approach works, and it's what I'll be using for this project. Thank you very much, Dylan. – ctrlaltdel Nov 19 '13 at 15:14
  • Hey no problem! Glad to hear it works. – Dylan Nov 20 '13 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.

| improve this answer | |
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.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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