I've got a quick announcement for those of you patiently waiting for the new version to be released.
I've got an experimental new feature deployed to the nitrogen_core master branch that I'd love some feedback on.
It's the employment of a new parse_transform (and new rebar dependency of nitrogen_core) to allow creating clones of records more simply.
You're making a new element which is largely based on another element. Let's say you're making a specific kind of dropdown box element that you want to copy basically all the fields of the base #dropdown{} element, but you want to add a few more options without.
Up until now, the process has required basically making a complete copy of the #dropdown{} record definition, calling it something like #mydropdown{}, and then in your element_mydropdown.erl file, copying all the fields from one record to the other, either manually with something painful like
Or using:
Rec2 = wf_util:copy_fields(Rec, #dropdown{}).
(the latter of which is slower, but significantly cuts down on the lines of code).
Both approaches are a little putzy.
With this new parse transform (called rekt:
https://github.com/nitrogen/rekt), you can create your own record definitions using the original record definition as the core, then adding your own fields or redefining existing fields.
Using the example above, say you wanted to add the field 'foo' with a default value of "myvalue" to the #dropdown{} record, you could do so with the -extend module attribute as follows:
-extend(dropdown, mydropdown, [{foo, "myvalue"}]).
The above would then create a new #mydropdown{} record definition that would be exactly the same as #dropdown{}, except it would add foo="myvalue" to the end of the record.
This works great, except that in Nitrogen, a new element also needs a new module definition, to fix this, we should actually define our #mydropdown{} like this:
-extend(dropdown, mydropdown, [{module, element_mydropdown}, {foo, "myvalue"}]).
This will properly tell the element which module should render the new element (just like how the rendering module is provided in the ubiquitous ?ELEMENT_BASE macro).
However, since this is such a common pattern, I've added a ?WF_EXTEND macro to allow us to quickly define our new element with this:
?WF_EXTEND(dropdown, mydropdown, element_mydropdown, [{foo, "myvalue"}]).
The arguments are:
?WF_EXTEND(OrigRecord, NewRecord, RenderModule, Attributes).
To go along with this, I've also added a new functions for faster field_copying. While wf_utils:copy_fields is guaranteed to work for copying fields from one element to another, wf_utils:fast_copy_fields is designed specifically to work with elements extended using ?WF_EXTEND (since it expects the same record structure plus a few fields).
Anyway, those of you experimenting with things, feel free to give this a gander and let me know what you think. You can pull from the nitrogen_core master branch, and run `make` from the root of your project to have it pull down `rekt`.
Also, feel free to have a look at the rekt definition. It's a pretty simple parse transform, and it's my first time digging around in parse transforms beyond a cursory glance, so if I missed or messed anything up, please call me on it, or feel free to put in a pull request.
Thanks folks, and have a great weekend!
-Jesse
--