Please upgrade here. These earlier versions are no longer being updated and have security issues.
HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.
Options

Theme: Controller Overriding and javascript excluding?

edited February 2010 in Vanilla 2.0 - 2.8
I am working a new theme for Vanilla 2. I really like the way Vanilla lets you override files by putting them in directories such as 'views/default.master.php'. I hit a wall, however, when I wanted to NOT import certain JS files such as 'jquery.menu.js'. It appears that this file is included in several controllers. The logical thing to do (I thought) was to put a directory and file in my theme called 'controllers/import.php'. This does not seem to work however.

So my question is: How can I exclude a javascript file from being included, and is it possible to override a controller?

Thank you!

Richard

Comments

  • Options
    SS ✭✭
    edited February 2010
    JS, CSS files are adding by controller, but you can overwrite headmodule by plugin (themehooks) and control output.

    In two words.
    1. Create custom HeadModule class
    2. Alter ToString() method: $Head = array_unique($Head); // removing dup ...
  • Options
    MarkMark Vanilla Staff
    Or you can make your theme pluggable, and access the existing HeadModule class to remove the offending js files...
  • Options
    edited February 2010
    @Mark, great addition! Having said that, HeadModule just isn't easy enough to work with for the purpose of removing JS, or at least CSS, as it might be stored in multiple locations, thereby changing the src URL. A better approach is to remove the JS or CSS before Vanilla even bothers to look for it, in the same way that it's added within controllers, at the AddJsFile/AddCssFile-level. That's why I added RemoveJsFile and RemoveCssFile in my fork at http://vanillaforums.org/discussion/10711/very-alpha-ckeditor-in-vanilla-2/#Item_1

    Now the only trick with the methods I've implemented is that the arguments given to RemoveJsFile have to be identical to the AddJsFile calls in the original files. In one case, there's a '/' before the same script URL on some controllers but not in others, so I had to look for it twice. Another approach might be to look solely for the filename at the end and remove based on that. A still better approach would be to refactor all CSS and JS into themes, or at least to decouple the presentational JS from the functional JS.

    Though of course, all this might be moot if you can switch on a presentational mode with cached and minified CSS and JS to speed up browser/server performance. At cache-creation time, you could perhaps first ear-mark the JS from applications, then plugins, then themes, then compile it all together into one file so as to not worry about it until a new app, plugin or theme is installed.

    Such caching would also mean that the HeadModule would show one script file rather than a dozen, and again that the HeadModule probably isn't the best location to be removing or adding JS/CSS.
  • Options
    MarkMark Vanilla Staff
    @Louis - Good ideas! What do you think would be the best way to move js into the themes? I'm imagining the root js folder gets all of it's files moved into the garden application's js folder, and all of the js files are added in the same way that the css & views are...
  • Options
    edited February 2010
    That's probably the most logical way about it, to treat the JS like any other theme or designable resource, since the JS relies on CSS selectors in HTML that could be overridden through views. So where views can be overridden, so too should CSS, JS and other files be overridden. And I guess the easiest way to then remove such files from being sent would be to place a blank file there instead (for CSS or JS) such that it includes the blank file rather than the file that comes with Garden.

    When you consider the idea of putting all your JS into one file for caching purposes, suddenly it makes more sense: look for all the JS in various folders by file name, and then merge them all into one file preserving the usual overrides, such that a blank file would mean adding a blank line (or nothing) to the CSS or JS rather than importing the original file. Perhaps what should normally happen is that each plugin or theme should create its own file nomenclature so they don't conflict each other, e.g. garden.discussion.js and that makes overriding that much more explicit.

    The idea of combining all the JS and CSS then makes it easier to contemplate having 20 plugins each with its own CSS or JS, or having view-specific CSS files. You can rest easy knowing that all those tiny files could be combined in to one timestamped cached file when in production and only updated when new themes/plugins/apps are enabled/disabled or on a manual schedule.

    If it were simple, I'd do an image sprites technique in a similar way, where all the GIFs, JPGs and PNGs were spliced together into one image, using background-position and width/height to offset and show one image out of the bunch. But it's more complicated than text, with color tables and compression, so it's still best done manually.

    The JS and CSS would probably be best separated again by function and style, perhaps to the point where your JS for selectors is kept in a separate file from the API-style JS of functions, just as you can break down CSS that applies to colours from CSS that structures the page to CSS that complements the JS. A stricter approach toward IDs such that every HTML object has a unique ID can really help with some forms of JS also, e.g. CKEditor instances. of textareas.

    Perhaps this is something I'll work on in the next month or two. First I want to finish writing more of the website application though, before I focus too much on performance optimization and such. If I come across something useful, though, maybe I'll try my hand at refactoring...
Sign In or Register to comment.