TYPO3 Flow meets Ember.js

Easing the use of TYPO3 Flow for Ember.js based web applications.

This is a Google Summer of Code project that will be implemented during summer 2013.
Work in progress. Feedback is highly appreciated.
Follow our Twitter account for progress updates.

Goals

Go from FLOW domain models to a web app that uses FLOW as backend and Ember.js as frontend LIGHTNING FAST!
  • Provide a loose coupling of TYPO3 Flow domain models and Ember data models through conventions.
  • Provide a FLOW REST API (controller, view, route part) that complies to the Ember conventions.
  • Provide a scaffolding/kickstart functionality to:
    • kickstart Ember models from Flow model semantics.
    • kickstart Ember controllers, views, handlebar templates for a basic ember-based user interface.

Concept

In order to provide a concise overview, I have created a diagram showing the components that a kickstarted application will consist of. Components that are kickstarted (generated) are illustrated with a green background. Components that are provided through a Flow package (cf. below Ember Commons Package) or are part of ember-data are illustrated with a blue background.

Architectural overview of a generated app

Kickstart

  • Kickstarting through command-line => extend FLOWs CommandController
  • Some settings for the kickstart can be configurated using a Yaml file (eg. Ember.yaml):
    • handling of namespaces, override existing files, simple merge, ...
  • How to define which model should be kickstared?
    • Options: All of a package or namespace OR explicit declaration of each model
    • Explicit declaration of each model
      • yaml config (or commandline parameters)
      • What to do if there is an association to an additional model? Probably just omit, as in explicit declaration we can assume that it was left out intentionally.
    • All of package
      • I think there currently is no API to retrieve all domain models of a given package name.
      • If possible, providing a ignore list would be reasonable.
  • Properties and associations of a model can be looked up using the ReflectionService of Flow
  • Namespaces:
    1. Generally remove the long namespaces of the flow models.
      • eg. Flow Classes/TYPO3/Blog/Domain/Model/Blog.php => Ember App.Blog
      • Problem: What if there is a model with the same name from a different namespace/package?
    2. OR add a pattern-based config into the yaml file
      • eg. Classes/TYPO3/Blog/Domain/Model/ => App.Blog.
  • Note: The naming decision also affects the names of routes to which ember tries to persist the models. Thus, it is connected to how the route part handles/forwards requests.

Communication

As illustrated in the architectural overview the Flow RestController communicates with the Ember RestAdapter via AJAX calls in JSON format.

  • Flow EmberRestController + EmberDataView <=== JSON ===> Ember DS.RESTAdapter

    • Flow Controller + View needs to conform to embers RESTAdapter conventions
    • Flow RoutePart needs to conforms to embers standard RESTAdapter routes
    • Set a namespace in Ember's RestAdapter for RoutePart prefixing

      • DS.RESTAdapter.reopen({ namespace: 'rest' });
      • eg. find all blogs => /rest/blog/

  • Note: Once, json-api has settled to a stable concensus, the REST API should be evolved to comply to json-api.

Templating

  • Handlebars is the templating engine used by Ember.js. Handlebar code can be defined in a script-tag directly in the html code or seperatly in a file. Handlebar templates can be precompiled which increases performance dramatically and additionally the precompiler runtime code of the handlebar library does not have to be loaded.
  • Handlebars code should be outsourced into seperate files to allow precompilation => clean seperation and mixing TYPO3 FLUID and handlebars syntax problems avoided.
    • It would be great to use normal on-the fly compilation of handlebar templates in development context and precompiled templates in production context (more advanced than: http://berzniz.com/post/24743062344/handling-handlebars-js-like-a-pro) => performance
    • Problem: How to precompile handlebar templates (possibly without dependencies on node, ruby or grunt);
      • Grunt Task
      • Assetic (needs https://github.com/gabrielgrant/node-ember-precompile, that uses node)
    • Consequence: Fluid not useable inside Handlebar Templates => Does not make much sense anyway!
    • Implementation Decision: Precompilation should be discussed together with a proper Asset management approach for Flow. Thus, an introduction of a build step for the javascript assets including handlebar templates would be great (cf. JS workflow below). But the implemenation of the Asset management is beyond the scope of this project.

JS workflow

  • How to extend generated javascript? => Ember.Object.reopen rather than editing generated code directly

    • Thus, regeneration based on updated flow models is possible (very basic merge functionallity similar to extension builder localconf handling)
    • Could use Flows FileMonitor to watch models and trigger automatic regeneration?

  • Development vs Production Context

    • javascript should be minified + concatenated for production
    • Bonus: handlebar templates should be precompiled for production + use handlebar-runtime (without compile method) => smaller filesize
    • Could use Flows FileMonitor to watch templates and trigger automatic precompilation?
    • Currently, Flow does not provide a proper Asset Management. The integration of Assetic would be great as it also offers precompilation of Handlebar templates. Fluid ViewHelper as Assetic wrapper? (https://github.com/kriswallsmith/assetic)

  • How to organize javascript files? My proposal:

    • Seperate folders for controller, model, ... files;
    • All models in one file;
    • Controllers, views and templates in seperate files

Packages

There should be three packages that are needed:

  • Ember Commons package contains:
    • EmberRestController, EmberDataView, RouteParts, ViewHelpers, ...
  • Ember Kickstart package contains:
    • Kickstart Command
  • App package:
    • Has composer dependency on commons package
    • Initially contains: (kickstarted) Flow models
    • After Ember kickstart command should contain:
      • routes.yaml with rest routes
      • index fluid template that includes javascript assets
      • ember + ember-data library, generated ember models, controllers, views, handlebar templates

Should use composer for dependency management!

Usage

  • From command-line for kickstarting a flow/ember app
  • Configuration of settings for kickstarting in ember.yaml
  • Future usage szenarios:
    • could be used for extension builder (option classic ui vs. ember ui)
    • could be used for fast development of TYPO3 Neos backend interfaces or a site builder (cf. Webratio)

Note

  • The mentor Rens Admiraal has already started a project that solves some of the challenges that this project is tackeling. Thus, it is desireable that what is described above as "Ember Commons" package is an enhancement of the existing project.