I'm working on re-developing an existing project written in php. The current company offers its users a 'bespoke solution' - meaning if they want certain parts of the software tailored to their needs.
From speaking to the developer, users are then moved from the 'global' version to their own 'custom' version and any updates that are rolled out to the 'global' version are manually then added to each custom version later.
In meteor, how would one go about replicating this? I'm thinking storing an array in the database with "their custom template names" and then with each page load, check database if any custom templates exist for that user - if yes then load that template else load the default (global) template.
The alternative is to clone the default project for every customer and spin up a separate server for them (Very expensive!!)
How does Facebook etc gradually roll out features - i believe its a similar concept.
Or is there a better solution to this?
If customization is only done at the level of templates then your proposed approach would work using Meteor's dynamic templates capability.
{{> Template.dynamic template=myTemplateName }}
You would define a helper for the enclosing template that would return myTemplateName. That function could execute your logic of looking for a custom template and if not found, defaulting back to a standard one.
Related
What I want to develop....
I am currently developing a SaaS-solution (Symfony2) to build HTML-presentations or better slide shows. Users can log into an administration UI and create presentations. This presentations can be played later. A presentation consists of elements. The elements can be images, texts, videos, pdf and more.
This element types should be encapsulated from the user interface. So extern developers can develop such new modules (element types) with defined interfaces and inject it into the system.
If a new module is finished, we move it to a specific directory in the symfony2 directory and the system detect the new module. No hardcoded-changes in the administration ui system should be neccessary.
Each module has a own "product-number". So we can use a database to enable or disable modules for different users.
What functions must be implemented by a module?
In the administration ui the user has the possibility to create a presentation and add elements of different types (the modules). User sees a timeline with the elements. When he clicks on an element, the editor for this element will be shown under the timeline (Parent-Child-View). Each module has different editors. A text-module needs other configuration-possbilities than an image-module.
So, in admin UI we need functions to edit elements:
createNewElement() creates new entry in the database (module has own tables, e.g. mod_text_elements)
renderEditorView() generates HTML which will be shown in the administration ui with module-specific inputs. E.g. image-upload/crop, WYSIWYG-editor, ...
saveEditorInputs() the module needs to handle the data entered in the editor and save it to the elements entry in the database
deleteElement() to delete an element
The output for the presentation:
Later we want to play this presentation. So a loop goes through the presentation elements and asks the modules of the element what and how to show it.
renderPresentation() to render (HTML) an element for the presentation
Database
I've made a little er-diagram of a possible solution to save the information about modules and elements in a database. The yellow entities are module-specific tables.
How to realize this in Symfony2?
My frist idea is to define an interface which have to be implemented by the modules. But which class has to implement this? Controllers?
Are modules = bundles?
How to realize the View-in-View of the editor? The editor of the module (e.g. renderEditorView()) should be viewed in the user interface of the administration ui.
I'd do it by hooking in to the EventDispatcher Component.
Your 'Master' Controller would define a set of events which correspond to the standard CRUD actions you've defined above ... onCreateNewElement(), onRenderEditorView(), etc. You'll probably find a dozen more to provide hooks for as you build your application (allowing plugins to add tools to a toolbar for example).
You'd define a Service (this doesn't HAVE to be a Controller Class), which looks for new 'modules' and adds their correctly-named methods as listeners for your custom application events.
Are modules = bundles? Well, that's entirely up to you. Are you going to provide a method for users to 'install' new modules specifically for your application? Then what a module needs to look like is entirely up to you. Are you going to slip Composer into the mix and allow modules to be installed that way? Places a couple of constraints on the structure, but still pretty much up to you.
How to realise the View-in-View? Again, that comes down to exactly how you define the interface for your 'Event Plugins' and what kind of access they have to resources like TWIG and YAML config.
The question you're REALLY asking is How do I add functionality to an application without hacking existing code ... and the answer is EventDispatcher. The rest is up to you.
There is another way to expand codebase with custom "modules": Dependency Injection Tags.
It works like this:
You create core of the app, which implements basic functionality and registers compiler pass which handles code extension
Modules can be part of the core app OR moved to external bundles
Each module must be registered in DI container with tag supported by your core app, so can be handled properly (adding menu positions, new element types as in your example)
Symfony DI compiles all services and stuff so all modules are available within app instantly (so you can for example iterate over collection of prepared items without need to dynamically building it)
In my opinion EventDispatcher is better for handling real-time actions, like sending notifications when new entity is created (e.g. controller/service dispatches event, some bundle subscribes it and send notification).
When you want to extend core I would recommend DI tags. Of course you have to build all the core (interfaces and whole architecture) so modules can extend existing services' data, then you only use your services.
Whole Symfony full-stack framework is based od this tags, so there is a lot of existing code to investigate for getting the concept.
Please let me know if it's clear enough what I wrote and what's in Symfony docs. If you need some additional info, I'll try to help.
How to edit and save back the default tridion template building blocks say for Ex(Default Finish Actions) provided by SDL?
Where can i found the soucre of default TBB's? After locating and editing the TBB's, how to save back in TCM?
Editing default templates provided by SDL is not supported. They are stored in DLL and there's no way you can customize it. Maximum you can do is to disable some of the templates from being created. Alternatively you can can create your own set of default templates.
You can use the Template Builder to assemble and (test) run Compound Templates (Page and Component Templates). You can access the Template Builder from the Tools tab in the Ribbon.
The default TBBs should not be changed.
.NET TBBs are either C# fragments with the code directly accessible, or classes that implement the ITemplate interface.
Please see the following blog post to get you started:
http://www.createandbreak.net/2011/11/template-building-blocks-via-net.html
The code for (an older version of) most of the Default Template Building Blocks can be found on the Tridion forum (http://forum.sdltridion.com).
(I don't have access anymore, but maybe somebody can edit my answer and provide the link)
As others have said though, you risk getting into support trouble if you simply modify and replace them. It might be better to:
take the code from the forum as a starting point
create your own variant, making the modifications you need
compile this into a new TBB
replace the standard TBB in the Default Finish Actions with your own variant
That way you can accomplish most things, without risking support problems. When they doubt whether you broke is, you can just swap out your own variant for the original and prove them wrong.
Every tutorial/example i can find for meteor shows a single view application. I would like to build something a little more complex. I'm unclear how to approach multiple views...preferably in a way that's somewhat scalable?
The iron-router package lets you access different views (layouts) by nice, REST-ful human-friendly clean URLs. It supports parameters in the URL, "loading" templates, waiting for subscriptions to finish loading, before and after hooks etc.
At this point you can only create Single Page applications with Meteor. Note that Single Page, doesn't mean you can't have several views - use iron-router for that.
But by design, Meteor serves a big fat unique JavaScript/HTML/CSS application down to the browser, though there's a feature request to allow incremental loading. It is then up to the application (or more precisely, the JavaScript framework), to dynamically render its views in order to display different "pages".
I was wondering the same thing and it took me way too much time getting something started. I finally got a paged app working solidly by using Backbone views and routes, so I created a simple boilerplate project to make setting up an app like this easier in the future.
Live demo here: backbone-boilerplate.meteor.com
Source code here: github.com/justinmc/meteor-backbone-boilerplate
Have you looked at madewith.meteor.com?
A bunch of apps there have multiple views using Backbone also Jonathan Kingston who created britto has started simple meteor framework called Stellar
At this stage of the game not sure if there really are best practices. But these two seem to be the current flow.
You can also make a tabbed interface for multiple views. There is a package project "Smart package for generating a tabbed interface with pushState" github project here: https://github.com/possibilities/meteor-tabs
The best solution right now is using a routing package (router is basic but works). The workflow is something like this:
declare routes; return a template name for each route
place the reactive helper provided by the package in your body tag
the reactive helper will return the template associated to that route
you create a template for each route and optionally set custom publish functions
Router will give you browser history (client side).
Note that at this time there are some limitation on the way Meteor handles html/js. They are load all at the same time. The bright side is that once the app is loaded, page transitions will be instant.
I'm trying to create a simple module to preview themes in Drupal. Each user has their own custom node and I want to be able to show them a preview of how the theme will work without them actually enabling it. Right now this is what I have:
function theme_preview_info($new_theme, $node_id)
{
global $custom_theme;
$custom_theme = $new_theme;
$node = node_load($node_id);
return $node->body;
}
It will display the content of the node, but the formatting is all messed up. How can I properly display the node exactly as it would as if i went to node/1, but instead view it at theme_preview/theme_name/1?
Do you have any experience building Drupal modules?
If not, you may find that what you are trying to do is not all that simple.
You will need some interface for the user to choose which theme they are previewing. Then, you will need to hook into Drupal's routing to direct users to the appropriate node using the selected theme preview based on a customized path alias (theme_preview/theme_name/1). There's most likely a lot of other back-end overhead that I'm not anticipating at the moment.
If you have experience with building Drupal modules, though, that might not be a big deal.
Switching out the theme is probably the easiest part. If you're in Drupal 7, you can use an implementation of hook_custom_theme() to change the theme used for particular nodes based on your intended criteria (i.e., which theme the user selected).
http://api.drupal.org/api/drupal/modules--system--system.api.php/function/hook_custom_theme/7
This way, you can actually allow Drupal and the selected theme to completely handle the rendering of the page, giving a more accurate preview.
I'm not sure how exactly you would go about creating the user's theme-switching interface or routing the user to a specific path alias for each theme selection.
You also might want to look into the ThemeKey module (http://drupal.org/project/themekey). It's possible you could use that module somehow to simply set up ab version of each node to be viewed in each different theme.
I have a few forms who's data needs to be written to the main database in their own tables. Just simple name-email collection forms, that are part of regular pages in drupal. I suspect the right way to do this would be to write a module that would have the query in a function, but this is just a guess. I've never written a module before, and don't know how the form would be processed that way.
It's also a guess that to perform the db query within a node would be insecure?
The only other idea I have would be to use a php file on the server to do the form processing, with the db query written there, but that seems very non-drupal, as far as I can tell.
How to??
http://drupal.org/node/508 is Drupal's info on module development
You'll be wanting to use the function "db_query()"
You can use Drupal's built in methods to build forms though that will save the data for you. Have a look at the module developers guide though and you should be able to figure it out. Module development sounds intimidating but it's not as hectic as it seems once you actually know what's going on with Drupal (hence, read the guide).
Have you checked what's already out there? Webform may be able to solve your needs without any custom code.
Also, I highly recommend the book Pro Drupal Development if you want to learn more about Drupal and basic module development.
I'd second the Webform module. Create a really simple webform with name and email (results can be emailed or stored automatically in the DB, and can be exported easily in several formats). Then check out the Webform Block module to put that webform in a block and place wherever you need it on your site. No custom coding required!
Here is an excerpt from the Webform Block project page:
Allows embedding a webform node into a block which can be positioned in any block region (theme space permitting).
Handles redirecting back to the current page on validation errors.
A good use for this is to add a site wide contact form inline on your pages, such as in the footer or sidebar.
Multiple webforms can appear on the same page. The contents of the block is simply a node, so theme work can be done in the node-webform.tpl.php file as usual.