How do I write a Jahia rule that runs when a node is published?
Question
How do I write a Jahia rule that runs when a node is published?
Answer
Use the DSL sentence A node is published, together with a condition on the node
type or a property:
rule "React to publication"
when
A node is published
- the node has the type mynt:myType
then
> logger.info("published {}", node.getPath());
end
Jahia ships four publication sentences, all backed by the same
PublishedNodeFact:
| Sentence | Matches |
|---|---|
A node is published | the node itself |
A translation is published | one language of the node |
A node is unpublished | the node itself |
A translation is unpublished | one language of the node |
Publish and unpublish are the same fact type, separated by a flag, so a pattern that does not constrain it will match both.
A publication emits more than one fact
This is the part that surprises people. Publishing a node that has internationalized properties emits a fact for the node and a separate fact per translated language.
Measured on Jahia 8.2.3.2, publishing one node with an English title:
| Rule | Times fired |
|---|---|
A node is published | once per listener |
A translation is published | once per listener, with lang=en |
raw PublishedNodeFact( unpublished == false ) | twice per listener |
The raw pattern fires twice because it matches the node fact and the
translation fact. That is exactly what the DSL sentences protect you from - each
one pins translation to true or false. If your rule is running twice per
publication, this is almost certainly why.
On the translation fact, getPath() returns the parent node's path, not the
j:translation_xx child, and getLanguage() gives you the locale.
It runs in more than one workspace
The same rule file is loaded by several listeners. In the same measurement, one
publication fired the rule once with workspace=default and once with
workspace=live.
So a rule in rules.drl reacting to publication runs twice, once per
listener. If you only want one execution, guard on the workspace global, which
is available in the consequence.
"Unable to expand" when you write the pattern by hand
A file that declares expander rules.dsl expects every line in when to be a
DSL sentence. A raw Drools pattern must be prefixed with >, or compilation
fails:
rule "broken"
when
$published : PublishedNodeFact( unpublished == false )
then
...
end
Errors when compiling rules in file [...] : [9] Unable to expand:
$published : PublishedNodeFact( unpublished == false )
The fix is the > prefix:
rule "works"
when
> $published : PublishedNodeFact( unpublished == false )
then
> logger.info("published {}", $published.getPath());
end
Both forms above were compiled on 8.2.3.2: the first produced that exact error, the second loaded and fired.
Remember that a hand-written pattern loses the translation == false constraint
the DSL sentence would have given you - which is the double-firing described
earlier.
This article was drafted with AI assistance, then reviewed and curated by Jahia Customer Support engineers before publication.