Closed FilipNest closed 7 years ago
Your description doesn't match what you have changed in the code, for example to embed a form you say to do:
{{{iris embed="form" formID="login"}}}
but for mail settings its:
{{{iris 'form' '{"formID":"mailSettings"}'}}}
That's a shortcut that made changing core easier. Both methods work. I can replace every instance with the longer method if needed and then take out the shortened one from the code. I have a list of all core forms so shouldn't be too tough to do. Unless keeping the shortened version in is a good idea. It's fairly harmless.
Not sure which is the better approach, im always dubious whenever i see hardcoded variables like embed="form" or formID="login" etc which are more likely to become depreciated and are less flexible than json.
I'm also seeing random bits like 'hook_entityview3' on line 301 of entity_fetch.js what does view3 mean?
Can you also explain the querycache?
This is such a massive change that is going to break everything, im struggling to see where the real benefits are. And now that we have actual client projects going live we just cant afford to keep making such big breaking changes. Is it possible to make it backwards compatible so that we can change to the new way?
Thanks for looking at this. I know it's huge!
Regarding old/new syntax. Before we had:
[[[form login,{"hello":"world"}]]]
which passed the hello
parameter to a form with a formID
of login
. We also had lots of forms and other embeds that were passing multiple comma separated parameters: sometimes strings, sometimes JSON.
With this we can do the same thing with keyed parameters/attributes. Their order no longer matters and we can use Handlebars helpers within them. They can even be grouped together in one embedOptions
parameter which is a JSON string of all options (like we had before). They're not less flexible than JSON because they're all full JSON strings (objects, arrays, booleans...).
The entity fetch/views stuff should probably go out. I've merged this through my Master branch which has been running this code for a few weeks now. hook_entity_view3 is a typo so I'll certainly fix that. (fixed). The query cache thing is a flag only function I put in when testing the performance of it. It's only activated when you add it to your launch config but I should probably take it out and merge back in afterwards.
Backwards compatibility could be achieved by some regex that replaces all of the old style embeds with the new ones. A module could maybe do that by hooking into hook_frontend_template
and attempting to replace all the old embeds on runtime. I'd expect it to be very messy but it is possible. Find and replace in a code editor may be easier for projects jumping to the new syntax.
The main advantages of this new system:
iris_handlebars_delay
type helpers we had before.Using Handlebars helpers for embeds seems like a much better option than packaging in our own like we were. It wasn't possible before but now the new Handlebars helpers Promises library mean we can do async helpers leaving no need to use our own system.
I'm running this code on my own fork for my projects at the moment but will leave this PR branch as is to work changes into for when you think it's ready to merge in. That way I can still make other Iris changes to a branch branched off this one but this will still be easy enough to merge in once you think it's ready.
Pop in any suggestions for improvements to this thread.
This is a breaking change but will hopefully be worth it. I've updated core to work but any embeds in site templates like forms, menus and tags will need changing to the new syntax to work with this.
Outcomes:
{{{{iris_handlebars_delay}}}}
as all Handlebars logic is now parsed in one go rather than several loops. Variables are available immediately.Guide to use
Here's a guide to how the new Handlebars-powered Iris embed system introduced in this pull request works.
Basics
Each embed is now put in using the following syntax:
Inline embeds
Triple brackets work in the same way as usual in Handlebars. If it's an embed that creates HTML, you'll need to skip the escaping by using three brackets.
Block embeds
Some embeds (currently only entity embeds but more like menus can come in the future) support block type embedding.
Note the
as
parameter that lists what the embed's return value's variable name within the block will be. This can then be used as normal inside the Handlebars block.Parameters
Parameters to an embed can be passed in the following ways.
param2 = current.title
param3='{"type":"hello"}'
param4='{"type":"$current.title"}'
embedOptions
JSON parameter with all the values you want to passembedOptions='{"title":"hello", "world":true}'
The special
liveupdate
parameterA
liveupdate
parameter is available for use on any embed type. Currently only the entity type uses it but any type can easily be converted to use live updating. The parameter sets everything up, all that's needed on the server side is a message to live update an embed template.Liveupdate API on the server side
Each time a websocket connection is made with the Iris server on a page with embeds marked with the liveupdate parameter, a registration message is sent to the server registering a listener on the embed for that current page view. As soon as the socket disconnects the embed listener is unregistered.
All the currently registered embed listeners are stored in an object called
iris.modules.frontend.globals.liveEmbeds
keyed as an object by the embed type.This contains information about the embed (all its settings) and the authPass and socketID of the user that registered a listener for it.
It has a
sendResult()
function that allows you to refresh the embed for the client. If you just want to check the result, or alter it before you send it to the client there's agetResult()
function.Permissions
Each embed stores the authPass of the user that registered it so the embed, if reloaded, is reloaded with the same permissions (If these permissions could have changed between the page load and the update event, an authPass can be sent to the
sendResult()
update function on each embed listener).Example update message function
Here's an example that updates all entity embeds across the system for every connected client:
Examples for current embed types
Forms
Forms need a formID parameter. Any other parameters will be passed into the form render hooks.
Tags
Tags have a
name
parameter for the tag container name and an exclude parameter that takes a JSON array of tags to exclude from the container.Messages
A user's messages can be shown with:
Menu
Menus take a
menu
parameter and an optionaltemplate
parameter that can override the menu template.Template
Template embeds simply take the template lookup you want to use to embed a template.
Region
Region embeds take a single
region
parameter.Entity
Entity embeds are used as block embeds. They take the same parameters as an entity fetch hook on the server side.
Additionally you can use
loadscripts=true
to load the fetched entity into a live-updating client side entity database for use with systems such as Angular.js . If this is used you can use thevariableName
parameter to store a friendly name for the clientside database collection.As mentioned above
liveupdate=true
will make the embed's contents automatically update if entity content changes in the database.