Publishing module

Collaboration Bundled: Community Edition

Edition

CE

License

MLA, GPL

Issues

Maven site

Latest

1.3.17

The module handles publishing of content from an author instance to a public instance. In DX Core, the functionality of this module is extended by the Publishing Transactional module, which ensures synchronization of content between multiple public instances.

Content publishing and content synchronization

Always wait with content publishing actions until all content synchronization tasks have been finished.

If you attempt to publish a page while the Synchronization module is mid-sync and hasn’t yet synchronized the page’s parent, the publishing process will fail.

Module structure

The module (parent) consists of four submodules. All of the submodules are required for the correct functioning of the publishing feature.

artifactID

magnolia-publishing-parent

Parent reactor.

     magnolia-publishing-core

Provides the main functionality.

     magnolia-publishing-sender

Handles send operations to the public instance.

     magnolia-publishing-receiver

Handles receive requests on the public instance.

     magnolia-publishing-app

Generates new publishing keys and provides a publishing monitor.

Installing with Maven

Bundled modules are automatically installed for you.

If the module is unbundled, add the following to your bundle including your project’s <dependencyManagement> section and your webapp’s <dependencies> section. If the module is unbundled but the parent POM manages the version, add the following to your webapp’s <dependencies> section.

<dependency>
  <groupId>info.magnolia.publishing</groupId>
  <artifactId>magnolia-publishing-core</artifactId>
  <version>1.3.17</version> (1)
</dependency>
1 Should you need to specify the module version, do it using <version>.
<dependency>
  <groupId>info.magnolia.publishing</groupId>
  <artifactId>magnolia-publishing-sender</artifactId>
  <version>1.3.17</version> (1)
</dependency>
1 Should you need to specify the module version, do it using <version>.
<dependency>
  <groupId>info.magnolia.publishing</groupId>
  <artifactId>magnolia-publishing-receiver</artifactId>
  <version>1.3.17</version> (1)
</dependency>
1 Should you need to specify the module version, do it using <version>.
<dependency>
  <groupId>info.magnolia.publishing</groupId>
  <artifactId>magnolia-publishing-app</artifactId>
  <version>1.3.17</version> (1)
</dependency>
1 Should you need to specify the module version, do it using <version>.

Configuration

Publishing is configured in Configuration > /modules/publishing-core.

Be very careful when modifying the configuration of publishing and always test the changes thoroughly before applying them to a live environment. Sometimes there may exist a better way of solving a publishing-related problem than by tweaking a publishing configuration.

Main part

The main part of the configuration is under /modules/publishing-core/config.

Node name

πŸ“ modules

     πŸ“ publishing-core

         πŸ“ config

             βΈ¬ publicationByPathVoters

             βΈ¬ publishingLogStorage

             βΈ¬ receivers

             βΈ¬ operations

publicationByPathVoters

Sets publication by path (default is by uuid) to configured workspaces.

Node name Value

βΈ¬ publicationByPathVoters

     ⬩ op

OR

     βΈ¬ config

         ⬩ op

AND

         βΈ¬ mgnlExchangeWorkspaceName

             ⬩ pattern

config

             ⬩ keyName

mgnlExchangeWorkspaceName

             ⬩ class

info.magnolia.publishing.voter.MapKeyPatternVoter

         βΈ¬ 1stAnd2ndLevelNodes

             ⬩ op

OR

             ⬩ class

info.magnolia.voting.voters.VoterSet

             βΈ¬ mgnlExchangeParentPath

                 ⬩ pattern

^\/[^\/]*$

                 ⬩ keyName

mgnlExchangeParentPath

                 ⬩ class

info.magnolia.publishing.voter.MapKeyPatternVoter

             βΈ¬ mgnlExchangePath

                 ⬩ pattern

^\/[^\/]*(\/[^\/]*)?$

                 ⬩ keyName

mgnlExchangePath

                 ⬩ class

info.magnolia.publishing.voter.MapKeyPatternVoter

     βΈ¬ resources

         βΈ¬ workspace

             ⬩ pattern

resources

             ⬩ keyName

mgnlExchangeWorkspaceName

             ⬩ class

info.magnolia.publishing.voter.MapKeyPatternVoter

publishingLogStorage

Defines where the information about publishing is logged. The default implementation (info.magnolia.publishing.monitor.MemoryPublishingStorage) keeps the information in memory.

Node name Value

βΈ¬ publishingLogStorage

     ⬩ class

info.magnolia.publishing.monitor.MemoryPublishingStorage

receivers

Contains the list of receivers where content will be published.

Node name Value

βΈ¬ receivers

     βΈ¬ magnoliaPublic8080

         ⬩ url

http://localhost:8080/magnoliaPublic

         ⬩ enabled

true

operations

Contains the list of operations provided by Magnolia and the respective operation classes:

  • publish

  • unpublish

  • commit (DX Core only)

  • rollback (DX Core only)

    You can define your own operations and add them to the list, but in this case, you will also have to implement your own send and receive operations. info.magnolia.publishing.operation.SendOperation is a base interface that all send operations must implement.

With a custom-defined operation, you can publish content to something that’s not a Magnolia public instance, for example to a custom API or a Content Delivery Network.

Node name Value

βΈ¬ operations

     βΈ¬ publish

         ⬩ receiveOperationClass

info.magnolia.publishing.transactional.receiver.operation.jcr.JcrTransactionPublicationOperation

         ⬩ sendOperationClass

info.magnolia.publishing.sender.operation.HttpPublicationOperation

     βΈ¬ unpublish

         ⬩ receiveOperationClass

info.magnolia.publishing.transactional.receiver.operation.jcr.JcrTransactionUnpublicationOperation

         ⬩ sendOperationClass

info.magnolia.publishing.sender.operation.HttpUnpublicationOperation

     βΈ¬ activate

         ⬩ receiveOperationClass

info.magnolia.publishing.transactional.receiver.operation.jcr.JcrTransactionPublicationOperation

     βΈ¬ deactivate

         ⬩ receiveOperationClass

info.magnolia.publishing.transactional.receiver.operation.jcr.JcrTransactionUnpublicationOperation

     βΈ¬ commit

         ⬩ receiveOperationClass

info.magnolia.publishing.transactional.receiver.operation.jcr.JcrCommitOperation

         ⬩ sendOperationClass

info.magnolia.publishing.transactional.sender.operation.HttpCommitOperation

     βΈ¬ rollback

         ⬩ receiveOperationClass

info.magnolia.publishing.transactional.receiver.operation.jcr.JcrRollbackOperation

         ⬩ sendOperationClass

info.magnolia.publishing.transactional.sender.operation.HttpRollbackOperation

lockManagerMode property

The property has been introduced with module version 1.2.6. By default, path-based locking is configured using lockManagerMode=path. Node-based locking can be set with lockManagerMode=compatibility.

The setting is applicable only on public instances. Changing the property on the author instance has no effect.

Publish and unpublish commands

Users typically publish content by clicking Publish in the Action bar. The click executes a publish command which pushes the content from the author instance to the public instance(s). Conversely, when users click Unpublish the system executes an unpublish command which deletes the content from the public instance(s).

The publish and unpublish commands are configured in /modules/publishing-core/commands. The default catalog contains the commands which just publish the content without versioning. Magnolia also provides a versioned command catalog. It contains identically named publish and unpublish commands which first version the content and then delegate to the default commands.

Both in the default catalog and in the versioned catalog, the command tree contains also the activate and deactivate commands (not shown below), which extend the publish and unpublish commands, respectively. The two commands are included in the configuration for compatibility reasons.

To use one of these commands, define the catalog and the command name in the action definition. See an example in Executing commands with actions.

Property Description

params

optional

     rule

optional

The rule property is useful when recursively performing a command. Adding the allowedTypes property under the rule property lets you define what should be included on each page. In particular, you can specify nodes such as areas and components, but not subpages.

Available classes:

  • info.magnolia.cms.util.Rule

For example, let’s take the recursive publishing action defined in the configuration below. Using the recursive property means a version is created for every page in the tree. On each page, only objects below page level, such as area or component, are included in the new page versions because of the node type mgnl:contentNode.

Example configuration
...
  publish:
    icon: icon-publish
    $type: jcrCommandAction
    command: publish
    catalog: versioned
    availability:
      rules:
        notDeleted: *notDeleted
          isPublishable: &publishableRule
            $type: jcrPublishableRule
    params:
      recursive: true (1)
      rule:
        class: info.magnolia.cms.util.Rule
        allowedTypes: (2)
          contentNode: mgnl:contentNode (3)
1 Recursive publishing command.
2 The allowedTypes property determines what is included in each page version.
3 Allowed node types set to mgnl:contentNode.

     modifiedOnly

optional, default is false

Security setting that prevents cookies from being read by a potentially malicious code.

     recursive

optional, default is false

When you publish a node and its children, you often end up publishing content whose status is already Published.

Such nodes don’t need to be published, but it’s often more convenient to just publish the whole tree than node-by-node.

To improve the performance of the author instance:

  • Exclude the already-published nodes from the action.

  • Publish the modified nodes only.

This may also help improve scalability, especially in cases where the author instance has a high concurrent load, typically with many editors activating large amounts of content at the same time.

     version

optional

Version of the node to be published.

If not specified, the current state of the node will be published. The property can only be used with recursive=false.

     versionMap

optional

Versions of the node to be published.

If not specified, the current state of the nodes will be published. The property can only be used with recursive=true.

     itemsPerRequest

optional

If defined, instead of transferring nodes one-by-one, the publication process transfers the subtrees that have fewer descendants in one transaction than defined using the itemsPerRequest property.

If the number of descendants is higher, each child will be published one-by-one, which is the same as when itemsPerRequest isn’t defined at all.

It’s therefore better to split flat structures into sub-folders for itemsPerRequest to take effect.

For more suggestions regarding the itemsPerRequest property, see the Configuring itemsPerRequest section below this table.

Setting the itemsPerRequest property causes the modifiedOnly property to be ignored.

     ordering

optional, default is fast

Defines the order in which nodes and their siblings are published on a public instance.

For further details, see Optimizing ordering on the public instance.

Configuring itemsPerRequest

Determining the value of itemsPerRequest depends on how much data you want to send in one HTTP transaction.

It could be, for example, 100 nodes for workspaces without binary data. For the assets workspace, 100 assets might be too much though, depending on the average size of your assets.

You can get an approximate size of data in one transaction by exporting the trees and checking the size of the exported files.
This doesn’t support publishing versions. Therefore, it’s not supported for apps with a publication workflow.


How does itemsPerRequest work?

Consider the following tree structure.

'tour-types':
  'active': {}
  'destinations':
    'europe': {}
    'asia': {}

If you publish /tour-types without itemsPerRequest defined, each node is sent to public instances separately:

INFO  ing.receiver.operation.jcr.JcrPublicationOperation: About to update content under path [/tour-types/destinations].
INFO  ing.receiver.operation.jcr.JcrPublicationOperation: About to update content under path [/tour-types/destinations/asia].
INFO  ing.receiver.operation.jcr.JcrPublicationOperation: About to update content under path [/tour-types/destinations/europe].
INFO  ing.receiver.operation.jcr.JcrPublicationOperation: About to update content under path [/tour-types/active].

Now, for the publish action in the tourCategories.yaml app, let’s set itemsPerRequest to a very small number (just for demonstration purposes):

subApps:
  browser:
    actions:
      publish:
        params:
          itemsPerRequest: 2

Publish /tour-types again.

  • It first tries to publish the whole /tour-types subtree, but it has too many descendants compared to the itemsPerRequest. So, the /tour-types folder has to be published separately.

  • /tour-types/destination has two descendants, and so fits the itemsPerRequest. Therefore, it will be published including its children in one transaction.

  • /tour-types/active doesn’t have children, so it’s published separately. The itemsPerRequest param doesn’t have any effect.

INFO  ing.receiver.operation.jcr.JcrPublicationOperation: About to update content under path [/tour-types].
INFO  ing.receiver.operation.jcr.JcrPublicationOperation: About to update content under path [/tour-types/destinations].
INFO  ing.receiver.operation.jcr.JcrPublicationOperation: About to update content under path [/tour-types/active].

In this example, we decreased the number of transactions to just a few. In practice, you can reduce the number of transactions from thousands to dozens, provided the workspace structure has been created as a more or less balanced tree.

Detection of publication failures

The configuration settings in this section are designed to enhance the resilience of all publication requests sent by the publishing module. They address intermittent connection issues by enabling automatic retries, preventing the need to roll back entire publishing transactions.

You can configure the number of retries, the interval period between retries, and header conditions for retry. Configuration is via a .yaml decoration, as shown in the example below. The properties and their default values are described in detail in the properties table.

light-module/decorations/publishing-core/config.yaml
retryConfig:
  retryWait: 3
  retries: 20
  retryHeader: <HEADER_1>, <HEADER_2> (1)
1 Comma-separated response headers.
Property Description

retryConfig

optional

If a publication attempt results in a 5xx code (server error) and the response header contains something listed in the retryHeader property, then the publication attempt is repeated.

     retryWait

optional, default is 2 seconds

The interval period between successive retry attempts.

     retries

optional, default is 10

The maximum number of retries before a publishing request fails and is rolled back.

     retryHeader

optional, default is l5d-proxy-error

A 5xx server error code and any header listed in this property cause the publication request to be retried.

Disabling publishing

If necessary, you can disable publishing on the public instance(s) by adding the enabled node in Configuration > /server/filters/publishing and setting its value to false.

How publishing works

For an overview of how publishing works see the Publishing overview page.

Feedback

DX Core

×

Location

This widget lets you know where you are on the docs site.

You are currently perusing through the DX Core docs.

Main doc sections

DX Core Headless PaaS Legacy Cloud Incubator modules