Modular architecture to encapsulate functions in Symfony2 - symfony

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.

Related

Asp.net Core 2 Domain dependent View selection?

I have a new multi-tenant web application in ASP.NET Core 2.0, single DB.
I've established a method of determining a particular request's 'TenantId' by examining the domain in a simple piece of middleware.
I've also established a DataContext which applies TenantId filters to applicable tables as needed.
The last thing I'm unclear about is how I can differentiate Views/partial views based on the TenantId whilst sharing the controllers.
I think some scheme where the app first looks in some kind of TenantId sub-folder for the customized tenant's view and if it can't find it, it goes through the regular steps to locate the view... might work okay? Is this a reasonable approach? In other words, it should use the specialized tenant view if it exists, otherwise use the default view.
Would this involve building a custom view engine of sorts?
I've tried something similar with tenant based Html fragments, but it was a pain maintaining it, so I'm looking for something more straight forward on this project.
I'm open to other suggestions of how to implement this functionality as well.
Thanks in advance!
You don't need a whole custom viewengine, you can implement an IViewLocationExpander to make it check various locations for views.
In my project I have mutliple tenant support with both shared themes and tenant specific themes. I can override any view by dropping a copy below the theme folder, ie the main view could be Views/SiteAdmin/Index and I can override it in /pathtothemes/themefolder/SiteAdmin/Index
You can see my implementation of IViewLocationExpander here.
How you register your IViewLocationExpander is like this:
services.AddMvc()
.AddRazorOptions(options =>
{
options.ViewLocationExpanders.Add(new cloudscribe.Core.Web.Components.SiteViewLocationExpander());
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
;

Defining structure for content in drupal

I am trying to create a site that will enable users to publish their projecs and enlist other people to join their project.
A user should be able to list a project, specify certain attributes (name,description, etc..).
There are few things i'm having trouble with.
First, by default publishing content is refered to as "content", i dont want a user to "add new content" but rather to "list new project".
Second, a project should have certain attributes, some optional and some mandatory, rather then the default title and body,
users should later be able to filter by these attributes when searching for projects.
is there a way to define the structure of content?.
Third, a user should be able to apply to a project, if he applies, the owner of that projects should receive the appliance, and accepte\reject.
In case he accepts, the users profile should be added a record that he is part of that project.
I am completly new to Drupal, and CMS in general.
My main expertise is with java, and I initially thoght about building the site with a java REST api in the backend and angular js in the frontend, but I have 0 experience with security and dodn't know how to do the user authentication and session management.
So I am currently trying out Drupal.
Is Drupal the right solution?
If so, how should I approach the requirements specified above?
Drupal (assuming that you are talking about version 7 since 8 is still in beta) is pretty powerful CMS, with a lot of (free) modules allowing it to expand it's possibilities.
When you are in back-end under Structure -> Content types you can see all available content types defined. There is also link "Add content type" which you can use to define your own. That basically means you can add any fields in any types you want. If you don't see the field type you need there is a big chances that there is a module which adds that field type so you just have to install it. You can also remove body (hide it actually), but title must remain (but you don't have to show it on front-end).
There is a "node reference" field type, but you have to install a module for it: https://www.drupal.org/project/references
So you can create dependencies you like.
And that "add new content" is just a link - you can create your own, set title as you like, just keep the same path. You can also set different theme for (some) admin pages if you want them to look differently. Under Structure -> Menus you can even edit admin menu, add new link and stuff..
Drupal is a bit heavy on resources, because of it's complex structure and database abstraction. For static content just turning on (built in) caches will help, but generally adding some additional caching mechanism won't hurt.

Can Sitecore templates be used to store SQL Queries or JavaScript

We are building a Page with dynamic functionality using ASP.NET + Sitecore 7.0.
Is it practical and appropriate use Sitecore templates for:
SQL Stored Procedure Name to be invoked
JavaScript to be invoked
ColumnNames to be used etc (related to coding customization)
Or should these configuration properties remain inside the ASP.NET Project itself?
What is the primary purpose of Data Templates in Sitecore?
Are they for developer customization or customer-level customization?
The purpose of a data template in Sitecore is to define the set of fields for content items which inherit from that template. - Think of a data template as a class and the content items (pages) as instances of that class.
Templates are usually used to define the user-editable content of pages within a site, that being said you can have items to store information which is not managed by regular content editors. The question is where do you draw the line between things which should be put into Sitecore and things which should be a part of the solution. My advice is only put things in Sitecore if they need to be there. If you have to have the ability for editors or admins to configure those settings/properties.
I would say that putting SQL/ColumnNames is probably a bad idea unless you are building some sort of report builder interface in which case it may be essential?
Likewise with placing JavaScript into Sitecore; this can be OK in moderation (e.g. snippets of analytics code which content editors may want control over?). If you're placing whole libraries of JavaScript into Sitecore, you're probably doing it wrong.
One final point to note is findability/re-factorability of code: if you have code spread between Sitecore and your solution, it can make it very difficult to maintain as it is difficult to get a complete overview of code involved.

Best practices approach to multiple views in meteor?

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.

Override activity in workflow?

I have a complicated workflow for sending marketing emails to customers. There's something like twenty activities that decide who gets what kind of email.
95% of my activities are defined in a binary activity library. I assembled my main activity in visual studio.
For certain types of customer I want to have the activity in (say) step 25a behave differently than what I defined when I built it. We could load the activity from xaml hosted in a database.
One option is to clone the entire workflow for those customers, but that is a lot of code duplication.
Is it possible to override whatever the runtime uses to locate and marshal activities so that if my customer is left handed, one activity in the workflow is substituted instead of what I defined in the IDE?
I'm thinking of how you can override the ViewEngine in mvc to dynamically load ipad views or whatever. Is there something similar for loading activities?
You can't replace the activity in the workflow itself if it is compiled into the assembly. There are several options you can use though:
Use a dynamically loaded activity using the ActivityXamlServices.Load() and as XAML is just XML change the XAML before laoding it.
Use a wrapper activity in your workflow that only loads the actual activity at runtime and uses the WorkflowInvoker to execute it.
Separate the intent from the implementation by using an activity and an extension. The activity only grabs all inputs and the extension and calls a function on it. At runtime you can vary the actual implementation of the workflow extension depending on your needs.
Good news... I have built exactly what you need for this in Microsoft.Activities. For details see WF4 How To Invoke a Child Workflow as XAML and just yesterday I added support for tracking child workflows see Tracking Child Workflow with InvokeWorkflow

Resources