XP 5.3 publishing programatically, contentService.push?

Enonic version: 5.3
OS: Ubuntu14

The jslib does not contain a publish functionality.
How would I publish content from js or java?
I have found:
com.enonic.xp.admin.impl.rest.resource.content.ContentResource.publish(PublishContentJson)

That uses:
com.enonic.xp.content.ContentService.push(PushContentParams)

To push content to the master branch.

I tired to use this function, set up:
@Reference
public void setContentService( final ContentService contentService )
{
this.contentService = contentService;
}

But the content is not being published. No error is printed out in th console.

I have identified the problem:
The link to the service is generated with:
execute(‘portal.serviceUrl’, {module : module.name,service: ‘ansatt’ })

If the current branch is master, the link to the service will also direct to the master branch.

Now, when we execute the:
ContentService.push
method we get to a point where the versions are compared:
com.enonic.wem.repo.internal.entity.FindNodesWithVersionDifferenceCommand

But when we are in the master context: source( ContextAccessor.current().getBranch() ), the master branch is being compared with the master branch wich is (always?) the target.

So the conclusion is that publishing content when in master context will allways give no output since identical versions of content in master branch is being compared.

In my opinion there should be a way to specify the source branch programatically when pushing content or… have the execute(‘portal.serviceUrl’) have a branch parameter so services dealing with content can always be redirected to the draft branch?

Hi.

As you say, its no function in the content-library supporting this yet, but it is quite easy to create your own:

Firstly, I really recommend you to upgrade to 6.x where it is much easier to create your own library-functions:

Then have a look at our library implementation of e.g content.create:

And the corresponding java-handler:

Don’t hesitate to ask about the implementation if you are unsure about anything; Sadly, the documentation for creating library functions is lacking at the moment, but we will look into that.

Thanks, we have been using the libraries for a while, the Java code is instantiated from JS without problems.
What would you recomend to make the publishing work? (well it works in the draft branch context)
Should we ensure that the rest service links is always directed to the draft branch or is there a way to enforce a specific branch when executing a service or code like contentService.push?

There are runAs functions:
private T runAs( final PrincipalKey role, final Callable runnable )
{
final AuthenticationInfo authInfo = AuthenticationInfo.create().principals( role ).user( User.ANONYMOUS ).build();
return ContextBuilder.from( ContextAccessor.current() ).authInfo( authInfo ).build().callWith( runnable );
}

Is there any way to choose the branch of the context in which it is running?

If you are in the master-context and wants to push to draft-branch, try setting the target of PushContentParams to Branch.from(“draft”).

We didn’t want to have content that is invisible in admin, since it is reading from draft branch, so we always want to modify the data in the draft branch first and then publish it to master.
So we will just hardcode that the service will be accessed always in draft branch, so when the change is being initiated form master, it will always use draft as source for publishing to master.

I found out why I was getting a auto-magic master branch context when adressing the draft branch in the url:
https://discuss-3.enonic.com/t/xp-virutal-host-and-services/282?u=ksawery

Was it a config error on your side, or are there still problems?

Since the virtual host mapping from draft to draft is in place, the service is being executed in draft branch so the problem is solved.
Just thinking that it should be documented that the:
com.enonic.xp.content.ContentService.push
Always uses context for the source branch, and it’s not possible to change that when the service is being executed.
There might be scenarios where the change of context branch might be useful, would be nice to have a way to do that.

The change of branch is done via our Context class in Java. We will do the same for Javascript in our 6.3 release so that you can change the branch in this way (not specified and could be changed):

var context = require('/lib/xp/context');

context.run({
  branch: 'draft',
  user: 'some-user'
}, function() {
  // do what you want in that branch with specified user
});
1 Like

I tried to find a way to change the context branch before but didn’t find a way to do this with:
Context current = ContextAccessor.current();

didn’t find any set methods.
This is not so important now but might be good to have an example for the future.

The way this works is to “run” a method with a new Context. To execute new code using other attributes in a context, you can do it like this:

Context current = ContextAccessor.current();
ContextBuilder builder = ContextBuilder.from(current);
builder.branch("draft");

Context newContext = builder.build();
newContext.callWith(() -> {
   // ... code to be executed in context ...
});
1 Like