5 users online. Create an account or sign in to join them.Users
Symphony.UI Working Group
This is an open discussion with 75 replies, filed under General.
Search
i think this is a great idea, nils. thanks for taking the time to outline some general guidelines in which we can all start to discuss this topic further. one thing i’m confused about though - you have this:’
$.fn.symphony
but then beneath that this:
$.Symphony
though i use jquery extensively, but yet to write a plugin (soon, i hope), how do those two relate to each other? shouldn’t the latter statement be this instead:
$.symphony
in your first code block, you have this reference:
$.symphony.widgets[widget](this, options);
and then in the second block you have it slightly different:
$.Symphony.widgets.console
just wondering how they relate to each other since everything’s case sensitive.
Hi Nils,
I agree with the above and discussed some of this with Scott a few months back when he was rewriting the admin library.
I think Drupal have managed to make an API which works and functions well. It’s something we can take inspiration and learn from, particularly because they have built it to work in the admin side. For example, I like the way they have split up the api into things like “behaviour” and “settings”.
$.fn.symphony but then beneath that this: $.Symphony
The first one is a jQuery plugin, the second one is an object attached to jQuery. I’ve chosen the uppercase version to distinguish both.
$.symphony.widgets[widget](this, options);
So this was a spelling mistake I corrected above.
@Fazal: Can you tell us more about the Drupal API? I have to admit that the document you linked to is more confusing than enlightening …
Nils, thanks for taking the initiative to get this ball rolling. Sounds very promising.
database interactions (via AJAX)
Have had a JSON Backend API extension on the back burner for quite some time now. Maybe that’s something we should pursue alongside this project?
Have had a JSON Backend API extension on the back burner for quite some time now. Maybe that’s something we should pursue alongside this project?
That sounds promising.
I was thinking about two ways of interactions:
- retrieving entries via an AJAX request based on ids and
- saving changes for an entry based on its id.
@Fazal: I just downloaded the current Drupal build and had a look at the javascript source. Are you referring to the Drupal object which is split up like this:
var Drupal = Drupal || { 'settings': {}, 'behaviors': {}, 'themes': {}, 'locale': {} };
I’m not sure how Drupal manages themes but behaviors and local seem to be similar to what I called widgets and language.
The first one is a jQuery plugin, the second one is an object attached to jQuery
Ok. seeing the second one was a little confusing to me since i normally don’t attach an object to the jQuery namespace. Whenever i see $.something i usually expect to the right side of the dot to be a method attached to jQuery. Is there any benefit to attaching the Symphony namespace to the jQuery object other than not attaching more things to the global namespace? I would having
Symphony = {
version: '2.1',
widgets: {},
helper: {},
language: {}
};
would be less confusing.
Though, after looking at your example above, I see that you are initializing this via an anonymous function. so was your choice of attaching Symphony to jQuery simply to be able to have access to the object after instantiating it?
$.Symphony and Symphony should work both the same way. The former is proposed in the jQuery docs.
so was your choice of attaching Symphony to jQuery simply to be able to have access to the object after instantiating it?
Yes, this is a reason. But if Symphony is the preferred notation, it could easily be made accessible, too.
database interactions (via AJAX)
Is a nice-to-have, but should definitely be looked at last. I too have done some work on this, but it wasn’t that easy to make it generic enough to satisfy every requirement.
@nils, i just did a couple quick tests, and it seems like you would only be able to access Symphony if it’s attached to the window object. in your current proposal, we would need to access it as $.Symphony since $ attaches itself to the window namespace, and not any “children” objects.
this is a rather moot point, just wanted to clarify things, that’s all.
this is a rather moot point, just wanted to clarify things, that’s all.
Oh, I think this kind of talk is essential. If the admin.js will be changed, we should be sure to change it the most future proofed way.
@nils, oh you’re right. i was just glancing at the object and didn’t really look closely that the Symphony object would be holding the references to widgets you propose (at work talking to people aren’t great for my attention span).
anyway, i feel like it shouldn’t be attached to the jQuery object so that it can live independently on its own and also won’t be as confusing when you’re calling the symphony method that is going to be attached to the jQuery object anyway:
$('ul').symphony('console', {
selectable: 'true',
sortable: 'false',
draggable: 'false'
});
I don’t see it as a bad thing to have the Symphony object attached to the global namespace since that will be used as storage container for widgets and developers can store information in there instead of cluttering the global space.
Okay, so it should be like that?
Core
/**
* Symphony plugin for jQuery:
* calls widgets by name
*/
jQuery.fn.symphony = function(widget, options) {
Symphony.widgets[widget](this, options);
};
/**
* Symphony object:
* - stores current version number
* - offers widget object
* - offers helper functions (e. g. fading colors)
* - offers language support
*/
Symphony = {
version: '2.1',
widgets: {},
helper: {},
language: {}
};
Widgets/Extensions
(function($) {
/**
* Example widget that logs variables in the console:
* add extension code as function to the Symphony.widget object
*/
Symphony.widgets.console = function (elements, options) {
console.log(elements, options);
};
// Initialize widget by calling it via Symphony plugin
$(document).ready(function() {
$('ul').symphony('console', {
selectable: 'true',
sortable: 'false',
draggable: 'false'
});
});
})(jQuery.noConflict());
Looks pretty good, I’ve added the new duplicator jQuery plugin to the Symphony integration branch (or my master branch), it doesn’t use this setup however, you currently use it like so:
jQuery('.field-bilink > ol').symphonyDuplicator({
orderable: true
});
Using your setup this now becomes:
jQuery('...').symphony('duplicator', {...});
Correct? If so, why is it better than:
Symphony.widget.duplicator('.field-bilink > ol', {...});
And also how does Symphony.language work? I plan on converting languages to a JSON format so that they can be accessed from JavaScript, so it might work like the __ translation function does in PHP?
Sorry for the random questions, don’t have enough time right now to express my thoughts better!
jQuery('...').symphony('duplicator', {...});
Yes, that’s correct.
If so, why is it better than:
Symphony.widget.duplicator('.field-bilink > ol', {...});
Well, that way we could make use of jQuery’s plugin structure and allow chaining of Symphony functions with other jQuery functions which is - in my opinion - more convenient for developers.
And also how does Symphony.language work?
By now, it’s just a placeholder. I’m not sure about the ideal way of handling languages. But I think we somehow need to offer a bridge to the core translation function. Personally I don’t like the way the current implementation in admin.js works as you either have to edit the core file or append another javascript file to the head overwriting the original strings.
I think it would be great to have a function that takes language strings, sends them as a request to a php file that finally returns the strings converted into the current system language.
Does anybody have ideas for a better organization of the Symphony object?
Talking about consistency, it would be great to have a set of icons that fit to the current backend styles.
We have a bunch of designers here in the forum. Is there anybody with experience in icon development?
JavaScript API I’m all for, but I’d be tempted to put off languages and icons for now. There’s a worry of taking on too much. I think a single focus of redeveloping the existing JavaScript to be more extensible should be the primary focus for now. By this I mean we should first work to replicate the existing behaviour but in a more extensible “plugin” format, rather than introducing new ideas.
The ideas of translations and icons are good, but would be better discussed further down the line once there is a stable plugin architecture.
That’s just my opinion.
So it seems like Rowan has already done some work on this front, with a duplicator plugin? Would it be worth seeing Rowan’s work first and seeing how the two can be merged?
I think it would be great to have a function that takes language strings, sends them as a request to a php file that finally returns the strings converted into the current system language.
Not wanting to discuss the topic of translations too much (I’m advocating leaving this for now) but I really don’t see the benefit of translating using JavaScript. A PHP-based translation means:
- less processing on the client
- we already have the translation framework in place, and extensions can tap into it using the
__()function - with languages stored as a PHP array it is far easier to build a “Language Builder” extension to provide a UI to edit languages
Just because it’s possible doesn’t mean it should be done.
JavaScript API I’m all for, but I’d be tempted to put off languages and icons for now. There’s a worry of taking on too much. I think a single focus of redeveloping the existing JavaScript to be more extensible should be the primary focus for now.
Languages are handled in the current admin.js so it’s part of rebuilding the current functionality. You are right about the icon part though.
I really don’t see the benefit of translating using JavaScript.
At the moment translations are handled inside the JavaScript file (which is wrong in my opinion). That’s why I would like to see a way to request the translations via AJAX to keep things in one place.
I’m working with German translations of my latest extensions and it’s a mess at the moment. PHP alone doesn’t solve the problem. If the system allows interface translation, this features has to be accessible in the JavaScript as well as not all needed strings may be present in the HTML output of the interface (and it would be stupid to store all eventually needed string somewhere in a hidden element in the interface).
I agree with nick and nils to handle the translations with php. I’m not familiar with its abilities in terms language handling though. I think stripping that out of the core admin.js and using an Ajax request to get a json object of translations would be a better way to handle this. But there should also be an option to bundle the translations with the same backend request if need be.
Passing in something like “lang=en&locale=us” will bring up the american English translations while “lang=en&locale=gb” would return the British English translations. It would be nice if php can handle regions (aka locale) with multiple languages as well.
One thing that concerns me with the entire Symphony object is naming conflicts and overrides. There definitely needs to be some sort of check to see if a widget has already been instantiated so we don’t run into extensions overriding others that we have been hearing about. I’m not 100% sure what the book name is, I think it’s called Pro JavaScript Techniques by Dustin Diaz, but I believe there are good examples in there for the things we want to achieve.
sorry if some of this doesn’t make sense…its hard to do this from a phone!
Create an account or sign in to comment.
A few days ago we started talking about javascript compatiblity which resulted in the proposal to rewrite Symphony’s core javascript with extensibility in mind. As this is not related to the original discussion, I’m starting this thread to gather ideas for an enhanced javascript implimentation which separates two things more precisely:
The main problem of Symphony’s core
admin.jsis the fact that it is grown out of a custom tailored script which has been adapted to make use of the jQuery framework. At the time of this transition only few extensions based on javascript existed and the current admin javascript is an all-in-one solution which does not give full access to all user interface functions to extension developers.This thread is about making the core javascript more modular and extensible. It is not about creating a visual style for the backend.
Symphony UI behaviour
The current Symphony interface offers the following UI components:
These functions should be accessible for extension developers, which currently have to recreate each feature. Some of us - like myself - have been using
jQuery.UIfor this purpose, but it seems to offer to much unneeded features and options as it’s not focussed on the Symphony context.It would be great to offer extension developers a core
Symphony.UIframework which abstracts the interface behaviour. Thinking of this, a few internal changes would be desirable:Furthermore I’d like to propose a few additional features:
The last proposal results from my experience of creating the Mediathek extension which needed a tabbed interface. I’m sure other extension developers need similar things and create their own solution for this purpose. To keep a visually unified user interface it would be great if Symphony could offer this or a similar feature in a
Symphony.UIlibrary (styles and behaviour). There are some other questions that are solved on a per extension base momentarily: How to indicate inline deletion or preview features? How to indicate reodering?Interface Icons
Talking about consistency, it would be great to have a set of icons that fit to the current backend styles. I think the following icons are common and needed repeatedly:
Symphony.UI structural proposal
I’m not a professional javascript developer but this is my first proposal for a new structure of the core javascript (e. g.
symphony.ui.js):(function($) { /** * Symphony plugin for jQuery: * calls widgets by name */ $.fn.symphony = function(widget, options) { $.Symphony.widgets[widget](this, options); }; /** * Symphony object: * - stores current version number * - offers widget object * - offers helper functions (e. g. fading colors) * - offers language support */ $.Symphony = { version: '2.1', widgets: {}, helper: {}, language: {} }; })(jQuery);This way plugins could add their own functionality to Symphony by adding a new function in the
$.Symphony.widgetobject (e. g.symphony.console.js):(function($) { /** * Example widget that logs variables in the console: * add extension code as function to the $.Symphony.widget object */ $.Symphony.widgets.console = function (elements, options) { console.log(elements, options); }; // Initialize widget by calling it via Symphony plugin $(document).ready(function() { $('ul').symphony('console', { selectable: 'true', sortable: 'false', draggable: 'false' }); }); })(jQuery);There should be guidelines and best practices for all developers how to build Symphony extension based on javascript. A script template defining the basics would be great. Having a
Symphony.UIlibrary would minify the need of custom code in the extensions and could bind internal and external system components.Discussion
Please discuss this proposal.
Resources
Javascript compatibiliy
Rowan Lewis’ interface javascript
Symphony 1.7 icons