4

I was wondering if there is a way to create custom attributes, e.g.:

   <div data-sly-myAttribute="${whatever}"></div>

Just like custom JSP tags.

EDIT:

As of May 4, 2014, it was not possible, according to this blog. Is there any news on this?

Alfeu
  • 971
  • 9
  • 12
  • It would be great, indeed, to create custom attributes, that could, for example, eliminate the need of using @ context='styleString' explicitly. – andremw Mar 31 '16 at 14:05

2 Answers2

3

No, it's not possible to create your own block elements since that implementation will not conform to the specification [0]. There are more subtleties involved than just adding a new plugin, one of them being block elements priority when multiple blocks are used on the same HTML element; not to mention the fact that if this was possible nothing would stop you from overriding the provided plugins.

However, if you think that there's a need for a new block element then please send a pull request to the specification, with a well defined use case. Furthermore, it would probably help if you'd discuss your use case on the Apache Sling development mailing list [1] - maybe what you need is something that other developers have thought of as well, in which case collaboration definitely helps finding the best solution to the problem.

[0] - https://github.com/Adobe-Marketing-Cloud/sightly-spec/blob/1.2/SPECIFICATION.md
[1] - https://sling.apache.org/project-information.html#mailing-lists

Radu Cotescu
  • 534
  • 3
  • 10
  • We resolved our use case with another approach, but I'll definitely take a look at it in the future. I was thinking of something like Angular's attribute directives. – Alfeu Apr 04 '16 at 13:50
  • Sure there are use cases where you would like to extend the template engine to fit the customer needs. Why to close the APIs when they make the engine more dynamic and flexible You can still leave some core stuff locked out, but give the possibility to extend and adjust to the customer needs. I'm not talking about general stuff which would be valid use case for the specification, but even than ... You can't even write filter for the existing plugins, just RuntimeExtensions in case they are called. I like very Sightly, but never used template engine without possibility to extend in some manner. – d33t Sep 29 '17 at 14:05
0

EDIT: Looks like this is not doable at this point, since the impl classes that would be needed are not exported by the bundle they come in. Thanks to Radu Cotescu for pointing that out in a comment.

I'll leave my original answer below. If someone really needed or just wanted to you could fork the Sling repo on github and add/deploy your own plugin or simply export the necessary impl package and add the plugin to your own codebase



Looking through the Sightly source code you can see a list of what they call Plugins, which provide the implementation for each of the sightly block statements. Those can be found here: https://github.com/apache/sling/tree/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/plugin

This is just a guess, and I haven't tried it yet, but it seems like you may be able to provide your own class which extends org.apache.sling.scripting.sightly.impl.plugin.PluginComponent and is a Plugin OSGi service. I would try copying one of the existing Plugins and see if you can get it to work with a new name. Maybe the TextPlugin, it seems pretty straight forward.

Hopefully this will point you in a direction that will lead to some fun :)

Something like this perhaps

@Component
@Service(Plugin.class)
@Properties({
        @Property(name = Plugin.SCR_PROP_NAME_BLOCK_NAME, value = "foo"),
        @Property(name = Plugin.SCR_PROP_NAME_PRIORITY, intValue = 9)
})
public class FooPlugin extends PluginComponent {

    @Override
    public PluginInvoke invoke(final Expression expression, PluginCallInfo callInfo, final CompilerContext compilerContext) {
        return new DefaultPluginInvoke() {

            @Override
            public void beforeChildren(PushStream stream) {
                String variable = compilerContext.generateVariable("fooContent");
                stream.emit(new VariableBinding.Start(variable,
                        compilerContext.adjustToContext(expression, MarkupContext.TEXT, ExpressionContext.TEXT).getRoot()));
                stream.emit(new OutVariable(variable));
                stream.emit(VariableBinding.END);
                Patterns.beginStreamIgnore(stream);
            }

            @Override
            public void afterChildren(PushStream stream) {
                Patterns.endStreamIgnore(stream);
            }
        };
    }
}

then use it in a sightly file

<div data-sly-foo="${properties.jcr:description}">This text should get replaced</div>

I'll update this answer if I ever get around to trying it out.

note: I will say however, if you are trying to do this in an actual scenario there is probably a better way to solve the problem you're trying to solve this way. The sightly team has attempted to give us everything we need to do what sightly is intended to do.

Jordan Shurmer
  • 946
  • 7
  • 21
  • I tried this sometime back and it did not work. somehow the FooPlugin is not available in pluginregistry. so you end up with an error saying plugin foo does not exist. Anyway, we did not pursue this approach (creating a custom attr) for some other reasons. – awd Apr 03 '16 at 16:32
  • You will not be able to register custom plugins to support new `data-sly-*` block elements. Although OSGi has been used for DI, the `impl` package is not exported, therefore not visible outside of the bundle. – Radu Cotescu Apr 03 '16 at 16:47
  • Ah yes, that's good point @RaduCotescu. Updated my answer, and upvoted yours :-) – Jordan Shurmer Apr 04 '16 at 00:43
  • You can custom build `org.apache.sling.scripting.sightly` from source to export required packages. – awd Apr 04 '16 at 09:27
  • @awadheshv Indeed, I'll add that note as well – Jordan Shurmer Apr 04 '16 at 11:37
  • My advice still stands - if there's a need for more block elements discuss your use case on the Sling dev list or send a PR to the specification. Otherwise you risk breaking the implementation and then providing support will become rather difficult. – Radu Cotescu Apr 04 '16 at 14:22