AEM Sightly - Is it possible to create custom data-sly attributes? - aem

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?

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

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.

Related

Filter by method attribute in Doxygen

I am new to Doxygen but I want to use it for a technical documentation for our team.
The background: We have several services in .NET which are going to be called from a JAVA backend through RPC.
Therefore it is quite useful to have those services documented for the JAVA guys.
Using the Doxywizard did help in the first place, but it created a huge overflow of data, which I want to filter, but have no clue how to.
What I want to achieve is, that Doxygen ONLY will use methods, which does have a specific attribute.
For example:
[RpcMethod(id: "GetNumDemo", description: "A demo method")]
public async Task<int> GetNumDemo(JavaDTO dtoObject, int randNum)
I want to have the method within the documentation found by Doxygen since it has the RpcMethod attribute and also cause it have a JavaDTO object, I want to have this class documented as well.
But I am overwhelmed with it ... do you guys can help me? ... at least with a hint within the Doxygen documentation.
Read through the documentation and goodled

Use of Extbase Repositories in Symfony Command

Im upgrading an extension to work with TYPO3 v10. Since command controllers can not be used anymore, im migrating them to symfony commands as pointed by the documentation. Everything works smooth as heck except for the usage of extbase repository classes. No matter what i query, i never get a result. Since i can't find any useful information on the web and the documentation i hope this may be just something minor.
After debugging for a while i found out that the pid is not determined correctly while building the query settings. I find that kind of strange since my root template has these lines:
plugin.tx_myext.persistence.storagePid = 15403
module.tx_myext.persistence.storagePid = 15403
The repository instances are correctly injected by injectMyRepository() methods. I've tried using the extbase ObjectManager to fetch the class instances instead but the "error" stays the same.
Am i doing something wrong or is it not possible to use extbase repository classes in symfony commands?
After more research i found out that there is some bootstraping missing which results in extension settings (the storageID in my case) not being loaded. From what i've been reading, that behaviour seems intended to prevent extbase booting, i guess?
There is a reference to something similiar in the official documentation: https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ApiOverview/CommandControllers/Index.html#initialize-backend-user
Knowing that, i tried to find a method to initialize the missing settings which i could not find. So this does indeed seem like a missing feature.
I developed a workaround which i'm not too proud of, but it's better than nothing (or rebuilding everything to doctrine for that matter). If you stumble upon the same issue, here you go. Just insert and call this method before you fire your query:
public static function initializeConfigurationManager(): void
{
/** #var ConfigurationManager $configurationManager */
$configurationManager = GeneralUtility::makeInstance(ConfigurationManager::class);
$tmpConfiguration = $configurationManager->getConfiguration(
ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK,
'myExtensionName'
);
$configurationManager->setConfiguration($tmpConfiguration);
}
That approach exploits the singleton state of the ConfigurationManager. You simply inject the static template of your extension manually and every extbase compound (like repositories) will then use these settings from there on. Lovely.
Be aware however, this is prone to break with future internal changes.

Proper way to modify public interface

Let's assume we have a function that returns a list of apples in our warehouse:
List<Apple> getApples();
After some lifetime of the application we've found a bug - in rare cases clients of this function get intoxication because some of the apples returned are not ripe yet.
However another set of clients absolutely does not care about ripeness, they use this function simply to know about all available apples.
Naive way of solving this problem would be to add the 'ripeness' member to an apple and then find all places where ripeness can cause problems and put some checks.
const auto apples = getApples();
for (const auto& apple : apples)
if (apple.isRipe())
consume(apple)
However, if we correlate this new requirement of having ripe apples with the way class interfaces are usually designed, we might find out that we need new interface which is a subset of a more generic one:
List<Apple> getRipeApples();
which basically extends the getApples() interface by filtering the ones that are not ripe.
So the questions are:
Is this correct way of thinking?
Should the old interface (getApples) remain unchanged?
How will it handle scaling if later on we figure out that some customers are allergic to red/green/yellow apples (getRipeNonRedApples)?
Are there any other alternative ways of modifying the API?
One constraint, though: how do we minimize the probability of inexperienced/inattentive developer calling getApples instead of getRipeApples? Subclass the Apple with the RipeApple? Make a downcast in the getRipeApples?
A pattern found often with Java people is the idea of versioned capabilities.
You have something like:
interface Capability ...
interface AppleDealer {
List<Apples> getApples();
}
and in order to retrieve an AppleDealer, there is some central service like
public <T> T getCapability (Class<T> type);
So your client code would be doing:
AppleDealer dealer = service.getCapability(AppleDealer.class);
When the need for another method comes up, you go:
interface AppleDealerV2 extends AppleDealer { ...
And clients that want V2, just do a `getCapability(AppleDealerV2.class) call. Those that don't care don't have to modify their code!
Please note: of course, this only works for extending interfaces. You can't use this approach neither to change signatures nor to remove methods in existing interfaces.
Regarding your question 3/4: I go with MaxZoom there, but to be precise: I would very much recommend for "flags" to be something like List<String>, or List<Integer> (for 'real' int like flags) or even Map<String, Object>. In other words: if you really don't know what kind of conditions might come over time, go for interfaces that work for everything: like one where you can give a map with "keys" and "expected values" for the different keys. If you go for pure enums there, you quickly run into similar "versioning" issues.
Alternatively: consider to allow your client to do the filtering himself, using something like; using Java8 you can think of Predicates, lambdas and all that stuff.
Example:
Predicate<Apple> applePredicate = new Predicate<Apple>() {
#Override
public boolean test(Apple a) {
return a.getColour() == AppleColor.GoldenPoisonFrogGolden;
}
};
List<Apples> myApples = dealer.getApples(applePredicate);
IMHO creating new class/method for any possible Apple combination will result in a code pollution. The situation described in your post could be gracefully handled by introducing flags parameter :
List<Apple> getApples(); // keep for backward compatibility
List<Apple> getApples(FLAGS); // use flag as a filter
Possible flags:
RED_FLAG
GREEN_FLAG
RIPE_FLAG
SWEET_FLAG
So a call like below could be possible:
List<Apple> getApples(RIPE_FLAG & RED_FLAG & SWEET_FLAG);
that will produce a list of apples that are ripe, and red-delicious.

How to call a step from another step in Cucumber-JVM

In Cucumber (the ruby version) you can easily call steps from other steps and thus build hierarchical libraries of steps making it easy to write the Gherkin feature specifications in the most generic terms.
However it is not readily apparent how to do this in Cucumber-JVM and I have been unable to find documentation for it.
Let me be clear I am not interested in calling the step implementation function directly because I don't want to have to know what its signature is, nor to change the call every time the implementation changes.
Rather, I want to pass an arbitrary string that will go through the regex matcher and automatically find the matching step and execute it. Just as the engine runs all steps.
simple example of what I would expect syntax to look like to define synonym "logout":
When("user logs out") { () =>
d.executeScript("logout();")
}
When("logout") { () =>
Step("user logs out")
}
This functionality is not supported in Cucumber-JVM. (Note that the Cucumber Backgrounder document you link in your question describes using Steps within Steps as "an anti-pattern")
Essentially, we believe that Cucumber is a collaboration tool and that Gherkin is not a programming language.
You can see a longer discussion of how we arrived at this decision here
To call steps within step definitions, inherit cuke4duke.Steps in java
import cuke4duke.StepMother;
import cuke4duke.Steps;
import cuke4duke.annotation.I18n.EN.When;
public class CallingSteps extends Steps {
public CallingSteps(StepMother stepMother) {
super(stepMother);
}
#When("^I call another step$")
public void iCallAnotherStep() {
Given("it is magic"); // This will call a step defined somewhere else.
}
}
Example:
https://github.com/cucumber-attic/cuke4duke/blob/master/examples/java/src/test/java/simple/CallingSteps.java
Note: cuke4duke support scala as well
Calling steps within steps is a terrible anti-pattern that can easily be replaced by something much simpler.
Instead of one step calling another step, have both steps call the same helper method.
If you apply this pattern with rigour you and up with
step definitions that are all just single calls to helper methods
a suite of helper methods that collectively provide a test-api
The art of elegantly implementing your Cucumber scenarios now becomes a known programming problem as all your functionality is now directly in code in your programming language rather than being in some restrictive construct specific to Cucumber.
You can now
refactor your helper methods to provide cleaner interaces
use parameters to give methods greater power
use naming to give all your calls greater clarity
use a helper method as an entry point to a suite of extra functionality
use delegation to move functionality out of helper methods and into test service objects
...
Providing this separation can be initially challenging if you are not a programmer or not experienced in the particular programming language in use. However once you get past this initial hurdle the code you can and should produce will be much easier to work with than the tangled mess that inevitably occurs with step nesting.
In Cucumber each Step is a Method. That way, you can call other methods in any step that you want.
#When("^click on \"([^\"]*)\"$")
public void clickOn(String arg1) throws Throwable {
driver.findElement(By.linkText(arg1)).click();
}
#Then("^should see the static elements changing$")
public void shouldSeeTheStaticElementsChanging() throws Throwable {
clickOn();
}

Read remote properties

First of all, Hello everyone(/world) !
I am making an Eclipse RCP app' who needs to inspect some .properties located in some plugins who's Id I know at runtime.
I'd like to know if there is an easy way to read them, for example I know that in my plugin *org.anyname.myplugins.mypluginthatrocks I have a file named myawsomeproperties.properties*, how can I open it and read it easyly with a sort of getter/setter system like String getInProperties(String fileNameOrPath,String myPropertieId)
void setInProperties(String fileNameOrPath,String myPropertieId,String myPropertieValue)orString getInProperties(File file,String myPropertieId)
void setInProperties(File file,String myPropertieId,String myPropertieValue)or any other mean in that type if you get what I mean ...
Thanks in advance ^^
Well, if these are juste plain old properties, there is the good old ResourceBundle that will do the trick.
But, if you would like to do it, IMHO, a little bit cleaner, and in a more Eclipse oriented mind, I would suggest that you create a class that you use the NLS class, as explained here.