I see many jQuery plugins duplicating jQuery code into ‘Widget’ structures. It seems to be the prescribed way I guess. Or perhaps ‘what everyone does’. It seems illogical to me.
Yii has a beautiful structure that would allow expanding the jQuery core set of scripts rather than duplicating some or all of the jQuery code. Unfortunately, that part of Yii is written in such a way that we can’t really capitalize on it too well.
While CClientScript->registerCoreScript() ensures the (Yii chosen) jQuery base setup is published and available, all we have to work with is CClientScript->registerScript(). CClientScript->registerCoreScript() publishes the (Yii chosen) jQuery base setup into the (configurable) core scripts directory while CClientScript->registerScript() only “refers” to a URL where we have already copied our scripts. Since registerCoreScript() hashes the directory name, it isn’t too easy to use the same directory to copy our jQuery scripts into where Yii dynamically places the core jQuery scripts.
This would seem to hamstring the Widget developers who use jQuery since most (it seems) are using jQuery on the client side too. Now there is the counter balance of “who’s script wins”.
Question: Does it make sense to add an additional method to the CClientScript class that would allow additions to the core scripts?
Benefits:
With one simple call, and perhaps a (widget or general) configuration file, CClientScript->registerCoreScriptAddons($configName), developers could now add jQuery plugins to the Yii jQuery core (where it belongs) without duplicating jQuery repository code.
Minifying js becomes easier
Allows custom jQuery implementations to literally over write Yii implementations if required by the developer
Allows Widget js to stay with the widget (until published for the app)
Drawbacks:
Likely requires mods to CAssetManager->publish() to pick up the new directory from the widgets publishing js
requires mods to CClientScripts class
========
For those wondering how all this works…
========
After studying CClientScript->renderCoreScripts(), I see that:
CClientScript->getCoreScriptUrl();
or
CClientScript->registerCoreScripts();
(eventually) uses
CAssetManager->publish();
to copy files from
YII_PATH.'/web/js/source'
to a hashed directory name
If this is worthwhile, I’m offering to code this.
Worth discussing? Would like to hear from all the jQuery fanboys…
I agree about the sometimes unneccessary “widgetizing” of jquery plugins. I usually find it easier to configure jquery plugins directly in code instead of wrapping things up in a widget. And it’s easier to customize jquery widgets or use hidden options (like for example options.parse() or options.dataType for jquery autocompleter which are not supported in CAutoComplete).
But i don’t really understand your improvement. For now you could use AssetManager to publish your own jquery plugin js and use it in your scripts (even without a widget). Can you maybe give a simple practical example to show how your proposal would change publishing of js?
It appears folks have gone about creating a widget because the Yii core doesn’t include the jQuery plug in they need for their architecture (or more simply to produce the output they desire).
I’m proposing the Yii core provide a method to allow additions/mods to the core jQuery plug ins rather than necessitate writing “one-off” CComponents or widgets for each and every jQuery plug in that doesn’t exist in the core.
Here is the example: Let’s say we have a jQuery plug in named “filetree”. The core uses “packages.php” to configure the js files and dependencies. This could be extended to userland in the extensions directory where autoloader seeks userland classes to load anyway. The same conventions could be followed as those in the core:
create dir named /protected/extentions/filetree
create packages.php in filetree containing source + dependencies
create dir named /protected/extentions/filetree/source and add jQuery source
place the needed css files into the source directory as well
create a special, succinct version of a widget class:
class FileTree extends CWidget
{
public function init()
{
Yii::app()->clientScript->registerCoreScriptAddon(__CLASS__, dirname(__FILE__));
}
}
Depending on what is in the source directory and the packages file, I could register 1, 20, 50 jQuery plugins simultaneously. I’m not sure there is an alternative way to do that right now.
Note the method in the init() call. This method would publish the jQuery plug in source directory into the same repository as the existing Yii core jQuery repository (hashed or namedHashed directory). Since this widget is actively used (otherwise it wouldn’t be autoloaded), the scripts and css’ are automatically registered (registerScriptFile, registerCssFile).
If you look strategically there are flexibility features this may provide concerning the potential for other js frameworks being introduced on the fly (rather than just jQuery or replacing jQuery at the user’s choice). This would obviously take more thought.
The attached hacks work but I think it duplicates the script tags in the document header.
Not you…remember I’m the one learning here. You’re the master. I appreciate your insight. The client-server linkup just doesn’t make sense to me in Yii. The server (PHP) stuff is just beautiful. Like the remapScripts() method that uses the scriptMap member var - that’s really great stuff. But not what I’m trying to overcome.
Specifics of JS client integration seems fractured (to me). But I think my trouble just dawned on me. I don’t know which methods automatically & dynamically copy the Yii base jQuery (because there seems to be many) to one of several oddly named directories. Then I’m using various versions of jQuery code from different sources from different places.
So I don’t know what to avoid and or what to use to my advantage…it comes down to being a noob <grin>.
Where should I look, and if I document this for myself, how can I contribute back to the community?