Allow modules to choose the theme #168

Open
codevin opened this Issue Oct 11, 2012 · 25 comments

Comments

Projects
None yet
2 participants

codevin commented Oct 11, 2012

When distributing a new module, it will be nice if it can have its own UI (i.e. its own theme and layouts). That way, the users don't have to worry about including its blocks in existing theme. There is instant gratification - install it and see it working. (The assumption is that the module is completely responsible for its namespace, say /mypath.)

With this approach, I am also able to use calipso as application framework i.e. module becomes an independent application by itself, while leveraging all the good functionality of calipso framework.

The code change is simple. (The module sets 'res.theme' to a precompiled theme.)
(File: lib/core/Module.js)

   var theme=calipso.theme;
    if ( res.theme != null ) {
       theme=res.theme;
    }
    theme.render(req, res, function(err, content) {

And the module writer can keep a version of precompiled theme using this code base:
(File: Your module; define 'mymoduletheme' as variable.

        var themeConfig = calipso.availableThemes['mytheme']; 
        calipso.themes.Theme(themeConfig, function(err, loadedTheme) {
                  if (err) {
                          ...
                  }
                  mymoduletheme=loadedTheme;
       });

And in the handler function, one can then assign

     res.theme=mymoduletheme;
     res.layout='mylayout';
Collaborator

richtera commented Oct 13, 2012

I like the idea except how would it "merge" the stylesheets?
Assuming each theme is mostly centered on layout and not css it would work but otherwise we'd have to come up with a different way.

codevin commented Oct 14, 2012

The idea is mainly for the new type of modules which create the UI specific to them. So theme will necessarily have template section which will do option.getStyles(); and I don't seem to see a problem here... I will explore though.

For e.g. one could create a blog as an module with its own theme, and also leveraging other calipso modules (for e.g. for content, for content types, roles, user management and what not.) Then when one deploys this blog application as is, the UI is already good to go if user chooses the module's theme.

The idea is that this will make calipso help allow module writers to create embeddable components for application. For e.g. if I want to create a new app, I would get ready made

  • User management, roles etc.
  • Variety of authentication options
  • Flexible user profile management
  • Entity management with versioning, voting, tagging and what not. (Entities depending on user's application focus such as photos, songs, playlists, locations, bookmarks...)
  • iGoogle like UI based layout management to configure apps and blocks, like what drupal provides.
  • Clean capabilities for module management. Somewhat on lines of http://blog.getprismatic.com/blog/2012/10/1/prismatics-graph-at-strange-loop.html
Collaborator

richtera commented Oct 22, 2012

Are you using module templates?

Collaborator

richtera commented Oct 29, 2012

I am trying to figure out what kind of things you would want to put into the module specific theme. If you only need to put templates, then couldn't you just add the template to the template folder of the module? Since as we previously talked about merging css would be pretty hard.
http://calip.so/calipso-modules.html
and themes can override those files if someone wanted to in the future.

codevin commented Oct 29, 2012

Let me explain my usecase: A locally installed service where clickable mockups can be created and managed by a product team. (I chose calipso for the purpose as base framework, and right now working on a specific module for this purpose.) I would want end users to do exactly two steps: 1. Install calipso. 2. Install the mockup module. They should have readily working mockup site under particular URL.

And now, let us say, somebody contributes a totally independent 'mindmap' module, with its own theme/layout. Those already using calipso for mockup module, will not have any conflicts with this mindmap module. Nor do they have to do any specific setup, or fiddle with different blocks in the layout pages etc.. URL spaces for both modules would be different.

Both these modules should feel like they are independent applications. (Perhaps, another way to look at it is that themes are specific to URL paths. /mockups is one theme, and /mindmap is another theme.) These 'apps' may offer some simple controls for the user preferences, but definitely can't meddle with layouts and overall application experience.

Open issues as I see them:

  • Dynamically merging CSS: Right now I am directly embedding my CSS files in layout HTML. But we will figure out a way.
  • Using templates within module with native theme: Works without any change.
  • Forms layout: Currently form is autogenerated. For my purposes, I need template based control on form layout. Would be creating a separate issue on this and propose a design.
Collaborator

richtera commented Oct 29, 2012

I do understand the usecase. I guess my question was if you put layouts and templates for each module in the module templates folder then they will be private to the module until at a later date someone decides to make a new theme which includes your templates and overrides them. I guess we would need to come up with a good naming convention so that templates are not inadvertently overridden by themes just because there is a name collision. Is there something you cannot do by controlling the views within the modules templates? I do agree that the name collision problems is probably the most concerning thing. My thought was to allow the modules templates folder to supply layouts and templates but then allow override of those in any theme. However I have not specifically tested what and if there are breakages. To load a whole theme per module might be interesting but then modules would no longer play nice with each other when they are both on the same page, we'd have to require iframes or something like that.
I do like the idea of laying out forms using a template although most of this could be controlled with css as well unless you want to render completely different kinds of controls.
As to your comments at the end:
What do you mean with "• Using templates within module with native theme: Works without any change."?
Thanks
Andy

On Oct 29, 2012, at 2:02 PM, Vinod Kulkarni notifications@github.com wrote:

Let me explain my usecase: A locally installed service where clickable mockups can be created and managed by a product team. (I chose calipso for the purpose as base framework, and right now working on a specific module for this purpose.) I would want end users to do exactly two steps: 1. Install calipso. 2. Install the mockup module. They should have readily working mockup site under particular URL.

And now, let us say, somebody contributes a totally independent 'mindmap' module, with its own theme/layout. Those already using calipso for mockup module, will not have any conflicts with this mindmap module. Nor do they have to do any specific setup, or fiddle with different blocks in the layout pages etc.. URL spaces for both modules would be different.

Both these modules should feel like they are independent applications. (Perhaps, another way to look at it is that themes are specific to URL paths. /mockups is one theme, and /mindmap is another theme.) These 'apps' may offer some simple controls for the user preferences, but definitely can't meddle with layouts and overall application experience.

Open issues as I see them:

Dynamically merging CSS: Right now I am directly embedding my CSS files in layout HTML. But we will figure out a way.
Using templates within module with native theme: Works without any change.
Forms layout: Currently form is autogenerated. For my purposes, I need template based control on form layout. Would be creating a separate issue on this and propose a design.

Reply to this email directly or view it on GitHub.

codevin commented Oct 30, 2012

"• Using templates within module with native theme: Works without any change."

I meant that I ship a module + a theme combination. (Of course, they are still independent). The theme is meant for the app, and may use some of the other existing templates and their blocks (such as tagging block). Under the namespace (such as /mockups), this theme will be used by default as application UI (overriding site theme), and the mockup template drives the UI with its own blocks.

In essence, I am delivering a totally independent app using calipso platform. Yes, namespace management has to be cleaned up. For e.g. I want to register ownership for "/mockups", and then locally handle those URLs; and for unhandled URLs under this namespace, mockup template will be owner for error messages as well.

codevin commented Oct 30, 2012

If you follow drupal, there are many application-specific forks; see http://www.ministryofdrupal.org/Drupal_Forks_and_Distributions. For e.g. http://managingnews.com/ is a fork of drupal, but totally converted into dedicated application. And forks are bad; they reduce the reusability. And in such apps, the control over the theme/look-and-feel is of most importance.

In calipso, my example mockup module can become such a full-fledged app. It will use capabilities of calipso; neverthless acts as independent app to end user. That is the idea that I am talking about...

Collaborator

richtera commented Oct 30, 2012

I do understand. I am not convinced that having a theme per module is the right thing to do. Personally I would like to add all that functionality to a module (i.e. having it's own default theme) and still allowing a theme to override those things. This would require better name spaces for overrides though. But I need to think this through a little more. Your idea of dynamically loading a theme would work but it seems kind of inflexible if someone wanted to take that module and apply their own theme to it.
So in terms of your use case we need to solve that; I am just not sure about what the ideal way to solve it is.

Collaborator

richtera commented Nov 3, 2012

How much would adding a "public" folder in addition to the "templates" folder to each module help? We could make the static server so that it serves the files from all the public folders joined together. Making a new template which included those files in the future would then override those files.

Collaborator

richtera commented Nov 3, 2012

I made this change in the user module to illustrate. This is in the git repo but not yet published to npm.
The user modules now has it's own public folder that serves up some styles and images.
The login and loginPage template uses the files from there.
If the theme has copies of files in it's public folder it will be able to override those files.
Let me know what you think?

codevin commented Nov 4, 2012

Seems good idea. I will try to use it. In the meanwhile, I have made my current codebase available here: https://github.com/codevin/calipso-screenswiki/tree/devel. It is working code with lots of copy-paste, but I hope you get the intent.

Collaborator

richtera commented Nov 4, 2012

I see we need to resolve layouts. The theme.layout object won't get custom layouts from anywhere. We'll need to add capability to add module themes into there.
Checking.
Andy

On Nov 4, 2012, at 2:06 PM, Vinod Kulkarni notifications@github.com wrote:

Seems good idea. I will try to use it. In the meanwhile, I have made my current codebase available here: https://github.com/codevin/calipso-screenswiki/tree/devel. It is working code with lots of copy-paste, but I hope you get the intent.


Reply to this email directly or view it on GitHub.

Collaborator

richtera commented Nov 4, 2012

I made some steps toward this.

  1. I added a new branch called privateThemes in calipso. This has support for theme-extension.json in each module.
  2. I forked your repo and pushed changes to use this feature under richtera/calipso-screenswiki/tree/devel
    It seems to work but there is work to be done. For some reason in some cases it's using a "list" layout instead of a "view" layout. And the "screen-view" (which is the new name of view within the module) doesn't work as a normal content view since you're changing the item name from item.content to screens.item.content. Not sure what's the best to do but maybe you can look at the rest and we'll make the correct adjustments to calipso after that.
    I think having each module able to add new theme items into the current theme which then can be overridden by new themes is the right thing to do.

codevin commented Nov 8, 2012

This is good, appreciate adding these capabilities as needed. I will check it out over the weekend.

Collaborator

richtera commented Dec 2, 2012

If this works well I am planning to add it to the documentation. Were you able to try this out?

codevin commented Dec 3, 2012

It works, and no issues found so far. There will be other requirements for module-as-app, I will open separate issues for them as required. (For e.g. "/" should be configurable to be mapped to any module etc.)

I am in process of putting up a sample TODO application module for the same. Ideally on lines of typical express application, with its own internal routing, but leveraging all existing modules and themes from Calipso.

I filed this stackoverflow question: http://stackoverflow.com/questions/13666435/using-match-engine-of-node-js-express-module-independent-of-app-server

codevin commented Dec 6, 2012

I have now created a sample Todo app that can become a template for such module-as-app. Can you check it out?
https://github.com/codevin/todoApp .

/todo is registered as app URL base.

I have separated out the module specific code within _module.js. So one can cleanly develop over calipso.

Before we can release it for wider circulation, I need to add user module block for login/logout within local theme.

Collaborator

richtera commented Dec 6, 2012

How do I get _module.js? It's missing from the repo.
Andy

On Dec 6, 2012, at 1:28 PM, Vinod Kulkarni notifications@github.com wrote:

I have now created a sample Todo app that can become a template for such module-as-app. Can you check it out?
https://github.com/codevin/todoApp .

I have separated out the module specific code within _module.js. So one can cleanly develop over calipso.

Before we can release it for wider circulation, I need to add user module block for login/logout within local theme.


Reply to this email directly or view it on GitHub.

codevin commented Dec 7, 2012

Have updated now. Please check.

Collaborator

richtera commented Dec 7, 2012

That looks good.
Questions that come to mind are:

  1. If you wanted the app work as the "default app":
    should we add a default URL into the config so you can just tell calipso to put people to /todo when they reach for /?
    allow such app to default / and just override the main router with new handlers?
  2. To do login
    should we provide a more general way to allow the existing user module to be used?
    did you already come up with a way to use a different popup or form?
    Thanks
    Andy

On Dec 7, 2012, at 2:06 AM, Vinod Kulkarni notifications@github.com wrote:

Have updated now. Please check.


Reply to this email directly or view it on GitHub.

codevin commented Dec 7, 2012

You have identified both the issues, and I was going to open tickets for
them.

Here is my thinking: You essentially have two types of modules:

  • Helper modules: tagging, content, user management, ... - No default
    URLs, but are embedded in admin and other apps.
  • App modules: Portal, blog server, CMS system etc. - Under /app1,
    /app2, etc.
  • (And then, admin interface for basic management, should be under
    /admin).
  • Of course, map "/" to any of the app.

Let us open a new ticket for it.

User module: I am about to look into this, as to how to leverage it within
the example app.

On Fri, Dec 7, 2012 at 6:16 PM, Andreas Richter notifications@github.comwrote:

That looks good.
Questions that come to mind are:

  1. If you wanted the app work as the "default app":
    should we add a default URL into the config so you can just tell calipso
    to put people to /todo when they reach for /?
    allow such app to default / and just override the main router with new
    handlers?
  2. To do login
    should we provide a more general way to allow the existing user module to
    be used?
    did you already come up with a way to use a different popup or form?
    Thanks
    Andy

On Dec 7, 2012, at 2:06 AM, Vinod Kulkarni notifications@github.com
wrote:

Have updated now. Please check.


Reply to this email directly or view it on GitHub.


Reply to this email directly or view it on GitHubhttps://github.com/cliftonc/calipso/issues/168#issuecomment-11128947.

codevin commented Dec 9, 2012

Could you also support overriding of module template blocks in the private theme?

When I render user.login block within the application module (todoApp), I would like full control over how this block is rendered. In particular, the URLs like /login may have to be redirected to the application module.

Collaborator

richtera commented Dec 10, 2012

This would be tricky just in terms of figuring out which template would override which? Module, theme, module? I guess we could set a precedence level or allow renaming of template. Or did your other comment about the login screen take this into account?

codevin commented Dec 15, 2012

One more issue to tackle: When I use multiple app modules (usually copied from the template app module), I find that the layout names clash, and thus, the module's layout name is not loaded since one is already present with same name from previous app Module.

Of course, we can just rename the layouts of each new app Module. (And write this in documentation.)

But I was thinking if we can solve it elegantly - i.e. should module name be embedded in theme namespace?

We have are two different concepts:

  1. Module will want to override main theme layout with its own layout: We want the same name.
  2. Module layout will introduce new theme layouts, and these shouldn't clash with other modules i.e. when module is installed, it shouldn't require further tweaking around to ensure names don't clash.

I am undecided about this. Can we think of something?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment