Altering the TinyMCE per Theme

Topics: Customizing Orchard, Writing modules, Writing themes
Sep 8, 2011 at 7:21 PM

The TinyMCE editor has quite a few helpful menu items that not immediately exposed in Orchard. It's simple enough to just edit "orchard-tinymce.js" to do what I want, but I'd rather do it via the ResourceManifest in my theme:

    public class ResourceManifest : IResourceManifestProvider
        public void BuildManifests(ResourceManifestBuilder builder)
            builder.Remove("OrchardTinyMce"); //Remove default "orchard_tinymce.js" reference
            var manifest = builder.Add();            
I would imagine I could do something like this whilst staying within the bounds of my custom modules and themes. 
Any suggestions on how one might remove or replace resources referenced in the manifest in Orchard 1.2? Thanks.
Sep 8, 2011 at 7:23 PM

What happens when you try?

Sep 8, 2011 at 7:30 PM
Edited Sep 8, 2011 at 7:31 PM

Well, the HashSet being used to store the values is declared as internal to the ResourceManifestBuilder so there's no builder.Remove() currently.

I believe we would need to expose a public method for removing items from the set based on their key unless I'm overlooking a better way to do this without needing to touch the framework.

Sep 8, 2011 at 7:32 PM

I agree. Do you think you could submit a patch?

Sep 8, 2011 at 7:36 PM

I'd be glad to. Thanks for the quick reply.

Sep 8, 2011 at 10:55 PM

Based in Dave Reed's feedback, every resource is a shape, which mean by just adding the same file name to your module, and having a dependency on it, then it will take you file instead of the module's one. You don't need to create any code for this. Just add a file with the same name in your theme.

Sep 9, 2011 at 3:40 PM
Edited Sep 9, 2011 at 3:48 PM

If I add the "orchard-tinymce.js" script to the manifest from within my Theme and include my modified script with the same name within the Scripts folder in my Theme the definition set by the TinyMCE module is still the only reference.

From myTheme.ResourceManifest:

    public class ResourceManifest : IResourceManifestProvider {
        public void BuildManifests(ResourceManifestBuilder builder) {
            var manifest = builder.Add();
The file "orchard-tinymce.js" exists under "myTheme/Scripts".

I suppose I could just alternate Body-Html in my Theme and then require a different script altogether, but this may limit my flexibility in switching to the CKEditor or some other Html editor at will.

I would like simply any module that has Script.Require("OrchardTinyMce") to receive a reference from "../Themes/myTheme/Scripts/orchard-tinymce.js" instead of "TinyMCE/Scripts/orchard-tinymce.js" but I'm still missing the mark regarding how script and style resources behave as shapes.


Feb 1, 2012 at 2:56 PM

This question is super old and I'm sure you found the answer. But just in case -- you can't override orchard-tinymce.js from a theme, it must be overridden from a module. Themes aren't active in the Admin dashboard -- and therefore cannot contribute their copy of orchard-tinymce.js -- but modules are active in the dashboard so you can use them to override this file. 

Feb 6, 2012 at 1:24 PM

Thanks, TheMonarch, for wrapping up this loose end. This is a good gotcha to document. 

Jul 17, 2012 at 5:28 PM

Having tried all this today (also because of TinyMCE) I see the following (all tried with TinyMceDeluxe, which is dependent on TinyMce):

  • Scripts, unlike stylesheets can't be overridden simply by dropping a file with the same name into the module's respective directory.
  • Resources can't be overridden by adding an entry to the resource manifest with the same name.
  • Resources can be overridden from a resource manifest by also setting the version number, if it's greater than that of the original resource or the original resource has no version number.

I don't think this is how it should work. I'd expect that if module B depends on module A, and module B declares the same resources as A, then those of module B should be used (even if the Script.Require() call is from module A, like it is with TinyMCE).

Jul 17, 2012 at 5:51 PM

File a bug then...

Jul 17, 2012 at 6:36 PM
Edited Jul 17, 2012 at 8:36 PM

Scripts were overriden correctly in my case. As @TheMonarch pointed out, the theme isn't active in the admin dashboard which is the "module" from which I initially tried to override the TinyMCE config script. I haven't looked at the code in a while, but I got it working and I think my solution was just placing the script in a module which was actually active whilst the Admin theme is applied.

If I use Script.Require() in module B, which depends on module A, I want to use the script that module A registered unless module B has overriden that with a more specific (more local) version. I believe this should continue to be determined by convention.

If module B does override a script in A, I'm not sure I'd really want to enforce an implicit dependency of A on B.

If I wanted a view in module A to use the script defined in B, then I would override the shape (view) from A that references that script. This shape will use the most local script defined in module B.  

Imagine the case of both modules B and C depending on A. Say both B and C seek to override a script that A defines. Which script would A then use?

What if C depends on B which depends on A and C overrides a script defined in A. Would both B and A now reference the script from C?




Jul 17, 2012 at 10:30 PM

Good points!

My issue is that since resource names are global, I expect them to be overridable globally too (speaking about resource entries in resource manifests). Much like it's with injected dependencies: all the classes request the same IContentManager, so if I provide an implementation for it then this should be active for the whole site.

Anyway, I'd expect the file override to work like it does with stylesheets and this is an issue raised by others formerly too. Therefore I've opened an issue for this here.

Jul 18, 2012 at 12:23 PM

I understand now after taking a look at the issue you submitted. That's definately how I would expect it to work as well. I appreciate that you followed up on this.