本页可帮助您扩展多站点管理器的功能:
本页应结合以下内容阅读:
创作网站时会使用多站点管理器及其API,因此这些管理器仅用于在创作环境中使用。
多站点管理包含以下包:
主MSM API对象交互如下(另请参阅使用的术语):
Blueprint
( Blueprint
如在Blueprint配 置中)指定Live Copy可从中继承内容的页面。
Blueprint配置(Blueprint
)的使用是可选的,但是:
LiveRelationship
指 LiveRelationship
定Live Copy分支中的资源与其等效源/Blueprint资源之间的连接(关系)。
LiveRelationship
对象提供对转出配置( RolloutConfig
)、和与关系相 LiveCopy
关的 LiveStatus
对象的访问(引用)。/content/copy/us
中,从/content/we-retail/language-masters
的源/Blueprint创建Live Copy。 资源/content/we.retail/language-masters/en/jcr:content
和/content/copy/us/en/jcr:content
形成关系。LiveCopy
保存Live Copy资源与其源/Blueprint资源之间关系( LiveRelationship
)的配置详细信息。
LiveCopy
类可访问页面的路径、源/Blueprint页面的路径、转出配置以及子页面是否也包含在LiveCopy
中。LiveCopy
节点。LiveStatus
对象提供对的运行时状态的访 LiveRelationship
问。使用查询Live Copy的同步状态。
LiveAction
是对转出中涉及的每个资源执行的操作。
LiveActionFactory
创建 LiveAction
给定配置的 LiveAction
对象。配置作为资源存储在存储库中。
RolloutConfig
包含要在 LiveActions
触发时使用的列表。LiveCopy
继承RolloutConfig
,结果出现在LiveRelationship
中。
创建要与转出配置一起使用的自定义同步操作。 当已安装的操作不符合您的特定应用程序要求时,创建同步操作。 为此,请创建两个类:
com.day.cq.wcm.msm.api.LiveAction
接口的实现。com.day.cq.wcm.msm.api.LiveActionFactory
接口并创建LiveAction
类实例的OSGi组件。LiveActionFactory
为给定配置创建LiveAction
类的实例:
LiveAction
类包括以下方法:
getName
:返回操作的名称该名称用于引用操作,例如在转出配置中。
execute
:执行操作的任务。LiveActionFactory
类包括以下成员:
LIVE_ACTION_NAME
:包含关联名称的字段 LiveAction
。此名称必须与LiveAction
类的getName
方法返回的值一致。createAction
:创建的实例 LiveAction
。可选的Resource
参数可用于提供配置信息。createsAction
:返回关联的名称 LiveAction
。在存储库中使用LiveAction
配置节点存储影响LiveAction
实例运行时行为的信息。 存储LiveAction
配置的存储库中的节点在运行时可用于LiveActionFactory
对象。 因此,您可以向配置节点添加属性,并根据需要在LiveActionFactory
实施中使用这些属性。
例如,LiveAction
需要存储Blueprint作者的名称。 配置节点的属性包括用于存储信息的Blueprint页面的属性名称。 在运行时, LiveAction
从配置中检索属性名称,然后获取属性值。
LiveActionFactory
.createAction
方法的参数是Resource
对象。 此Resource
对象表示转出配置中此实时操作的cq:LiveSyncAction
节点;请参阅创建转出配置。 与使用配置节点时的常规情况一样,您应将其调整为ValueMap
对象:
public LiveAction createAction(Resource resource) throws WCMException {
ValueMap config;
if (resource == null || resource.adaptTo(ValueMap.class) == null) {
config = new ValueMapDecorator(Collections.<String, Object>emptyMap());
} else {
config = resource.adaptTo(ValueMap.class);
}
return new MyLiveAction(config, this);
}
以下对象作为LiveAction
对象的execute
方法的参数提供:
表示Live Copy源的Resource
对象。
表示Live Copy目标的Resource
对象。
Live Copy的LiveRelationship
对象。
autoSave
值指示您的LiveAction
是否应保存对存储库所做的更改。
重置值表示转出重置模式。
从这些对象中,可以获取有关LiveCopy
的所有信息。 您还可以使用Resource
对象获取ResourceResolver
、Session
和Node
对象。 这些对象可用于处理存储库内容:
在以下代码的第一行中,源是源页面的Resource
对象:
ResourceResolver resolver = source.getResourceResolver();
Session session = resolver.adaptTo(javax.jcr.Session.class);
Node sourcenode = source.adaptTo(javax.jcr.Node.class);
Resource
参数可以是不适应Node
对象的null
或Resources
对象,如NonExistingResource
对象。
当安装的转出配置不符合您的应用程序要求时,创建转出配置:
在 Blueprint 或 Live Copy 页面上设置转出配置时,您可以使用该新转出配置。
另请参阅自定义转出的最佳实践。
要创建新的转出配置,请执行以下操作:
开放CRXDE Lite;例如:
http://localhost:4502/crx/de
导航至 :
/apps/msm/<your-project>/rolloutconfigs
这是您项目的自定义版本:
/libs/msm/wcm/rolloutconfigs
如果这是您的第一个配置,则必须创建。
您不得更改/libs路径中的任何内容。
这是因为/libs的内容在您下次升级实例时被覆盖(而且当您应用修补程序或功能包时,很可能会被覆盖)。
配置和其他更改的推荐方法是:
在此Create下,创建具有以下属性的节点:
contentCopy
或workflow
。cq:RolloutConfig
将以下属性添加到此节点:
名称: jcr:title
类型: String
值:将在UI中显示的标识标题。
名称: jcr:description
类型: String
值:可选描述。
名称: cq:trigger
类型: String
值:要使 用的 转出触发器。从以下位置选择:
rollout
modification
publish
deactivate
单击Save All。
转出配置存储在您在/apps/msm/<your-project>/rolloutconfigs
节点下创建的转出配置节点下。
添加类型为cq:LiveSyncAction
的子节点,以向转出配置添加同步操作。 同步操作节点的顺序决定了操作的执行顺序。
仍在CRXDE Lite中,选择转出配置节点。
例如:
/apps/msm/myproject/rolloutconfigs/myrolloutconfig
创建具有以下节点属性的节点:
contentCopy
或workflow
。cq:LiveSyncAction
根据需要添加和配置任意数量的同步操作节点。 重新排列操作节点,使其顺序与您希望其发生的顺序匹配。 最顶层的操作节点首先出现。
单击Save All。
按照此部分中的步骤开发LiveActionFactory
并将其用于转出配置。 这些过程使用Maven和Eclipse来开发和部署LiveActionFactory
:
LiveActionFactory
口并部署OSGi包。Maven项目和Java类的源代码可在公共Git存储库中使用。
GITHUB上的代码
您可以在GitHub上找到此页面的代码
以下过程要求您将adobe-public配置文件添加到Maven设置文件。
打开终端或命令行会话并更改目录以指向创建项目的位置。
输入以下命令:
mvn archetype:generate -DarchetypeGroupId=com.day.jcr.vault -DarchetypeArtifactId=multimodule-content-package-archetype -DarchetypeVersion=1.0.0 -DarchetypeRepository=adobe-public-releases
在交互提示时指定以下值:
groupId
: com.adobe.example.msm
artifactId
: MyLiveActionFactory
version
: 1.0-SNAPSHOT
package
: MyPackage
appsFolderName
: myapp
artifactName
: MyLiveActionFactory package
packageGroup
: myPackages
启动Eclipse并导入Maven项目。
添加依赖项,以便Eclipse编译器可以引用LiveActionFactory
代码中使用的类。
从Eclipse项目资源管理器中,打开文件:
MyLiveActionFactory/pom.xml
在编辑器中,单击pom.xml
选项卡,并找到project/dependencyManagement/dependencies
部分。
在dependencyManagement
元素内添加以下XML,然后保存文件。
<dependency>
<groupId>com.day.cq.wcm</groupId>
<artifactId>cq-msm-api</artifactId>
<version>5.6.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.api</artifactId>
<version>2.4.3-R1488084</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.day.cq.wcm</groupId>
<artifactId>cq-wcm-api</artifactId>
<version>5.6.6</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.commons.json</artifactId>
<version>2.0.6</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.day.cq</groupId>
<artifactId>cq-commons</artifactId>
<version>5.6.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.jcr.jcr-wrapper</artifactId>
<version>2.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.day.cq</groupId>
<artifactId>cq-commons</artifactId>
<version>5.6.4</version>
<scope>provided</scope>
</dependency>
从项目资源管理器的MyLiveActionFactory-bundle/pom.xml
打开包的POM文件。
在编辑器中,单击pom.xml
选项卡,并找到项目/依赖项部分。 在依赖关系元素中添加以下XML,然后保存文件:
<dependency>
<groupId>com.day.cq.wcm</groupId>
<artifactId>cq-msm-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.api</artifactId>
</dependency>
<dependency>
<groupId>com.day.cq.wcm</groupId>
<artifactId>cq-wcm-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.commons.json</artifactId>
</dependency>
<dependency>
<groupId>com.day.cq</groupId>
<artifactId>cq-commons</artifactId>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.jcr.jcr-wrapper</artifactId>
</dependency>
<dependency>
<groupId>com.day.cq</groupId>
<artifactId>cq-commons</artifactId>
</dependency>
以下LiveActionFactory
类实现一个LiveAction
,用于记录有关源页面和目标页面的消息,并将cq:lastModifiedBy
属性从源节点复制到目标节点。 实时操作的名称为exampleLiveAction
。
在Eclipse项目资源管理器中,右键单击MyLiveActionFactory-bundle/src/main/java/com.adobe.example.msm
包,然后单击新建 > 类。 对于名称,输入ExampleLiveActionFactory
,然后单击完成。
打开ExampleLiveActionFactory.java
文件,使用以下代码替换内容,然后保存该文件。
package com.adobe.example.msm;
import java.util.Collections;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.wrappers.ValueMapDecorator;
import org.apache.sling.commons.json.io.JSONWriter;
import org.apache.sling.commons.json.JSONException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import com.day.cq.wcm.msm.api.ActionConfig;
import com.day.cq.wcm.msm.api.LiveAction;
import com.day.cq.wcm.msm.api.LiveActionFactory;
import com.day.cq.wcm.msm.api.LiveRelationship;
import com.day.cq.wcm.api.WCMException;
@Component(metatype = false)
@Service
public class ExampleLiveActionFactory implements LiveActionFactory<LiveAction> {
@Property(value="exampleLiveAction")
static final String actionname = LiveActionFactory.LIVE_ACTION_NAME;
public LiveAction createAction(Resource config) {
ValueMap configs;
/* Adapt the config resource to a ValueMap */
if (config == null || config.adaptTo(ValueMap.class) == null) {
configs = new ValueMapDecorator(Collections.<String, Object>emptyMap());
} else {
configs = config.adaptTo(ValueMap.class);
}
return new ExampleLiveAction(actionname, configs);
}
public String createsAction() {
return actionname;
}
/************* LiveAction ****************/
private static class ExampleLiveAction implements LiveAction {
private String name;
private ValueMap configs;
private static final Logger log = LoggerFactory.getLogger(ExampleLiveAction.class);
public ExampleLiveAction(String nm, ValueMap config){
name = nm;
configs = config;
}
public void execute(Resource source, Resource target,
LiveRelationship liverel, boolean autoSave, boolean isResetRollout)
throws WCMException {
String lastMod = null;
log.info(" *** Executing ExampleLiveAction *** ");
/* Determine if the LiveAction is configured to copy the cq:lastModifiedBy property */
if ((Boolean) configs.get("repLastModBy")){
/* get the source's cq:lastModifiedBy property */
if (source != null && source.adaptTo(Node.class) != null){
ValueMap sourcevm = source.adaptTo(ValueMap.class);
lastMod = sourcevm.get(com.day.cq.wcm.msm.api.MSMNameConstants.PN_PAGE_LAST_MOD_BY, String.class);
}
/* set the target node's la-lastModifiedBy property */
Session session = null;
if (target != null && target.adaptTo(Node.class) != null){
ResourceResolver resolver = target.getResourceResolver();
session = resolver.adaptTo(javax.jcr.Session.class);
Node targetNode;
try{
targetNode=target.adaptTo(javax.jcr.Node.class);
targetNode.setProperty("la-lastModifiedBy", lastMod);
log.info(" *** Target node lastModifiedBy property updated: {} ***",lastMod);
}catch(Exception e){
log.error(e.getMessage());
}
}
if(autoSave){
try {
session.save();
} catch (Exception e) {
try {
session.refresh(true);
} catch (RepositoryException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
}
}
}
public String getName() {
return name;
}
/************* Deprecated *************/
@Deprecated
public void execute(ResourceResolver arg0, LiveRelationship arg1,
ActionConfig arg2, boolean arg3) throws WCMException {
}
@Deprecated
public void execute(ResourceResolver arg0, LiveRelationship arg1,
ActionConfig arg2, boolean arg3, boolean arg4)
throws WCMException {
}
@Deprecated
public String getParameterName() {
return null;
}
@Deprecated
public String[] getPropertiesNames() {
return null;
}
@Deprecated
public int getRank() {
return 0;
}
@Deprecated
public String getTitle() {
return null;
}
@Deprecated
public void write(JSONWriter arg0) throws JSONException {
}
}
}
使用终端或命令会话,将目录更改为MyLiveActionFactory
目录(Maven项目目录)。 然后,输入以下命令:
mvn -PautoInstallPackage clean install
AEM error.log
文件应指示包已启动。
例如, http://localhost:4502/system/console/status-slinglogs。
13.08.2013 14:34:55.450 *INFO* [OsgiInstallerImpl] com.adobe.example.msm.MyLiveActionFactory-bundle BundleEvent RESOLVED
13.08.2013 14:34:55.451 *INFO* [OsgiInstallerImpl] com.adobe.example.msm.MyLiveActionFactory-bundle BundleEvent STARTING
13.08.2013 14:34:55.451 *INFO* [OsgiInstallerImpl] com.adobe.example.msm.MyLiveActionFactory-bundle BundleEvent STARTED
13.08.2013 14:34:55.453 *INFO* [OsgiInstallerImpl] com.adobe.example.msm.MyLiveActionFactory-bundle Service [com.adobe.example.msm.ExampleLiveActionFactory,2188] ServiceEvent REGISTERED
13.08.2013 14:34:55.454 *INFO* [OsgiInstallerImpl] org.apache.sling.audit.osgi.installer Started bundle com.adobe.example.msm.MyLiveActionFactory-bundle [316]
创建使用您创建的LiveActionFactory
的MSM转出配置:
使用标准过程🔗创建和配置转出配置 — 并使用属性:
publish
配置您在上一步骤中创建的转出配置,以便它使用ExampleLiveActionFactory
类。
开放CRXDE Lite;例如, http://localhost:4502/crx/de。
在/apps/msm/rolloutconfigs/examplerolloutconfig/jcr:content
下创建以下节点:
exampleLiveAction
cq:LiveSyncAction
单击Save All。
选择exampleLiveAction
节点并添加以下属性:
repLastModBy
Boolean
true
此属性指示ExampleLiveAction
类应将cq:LastModifiedBy
属性从源复制到目标节点。
单击Save All。
使用转出 配置创建We.Retail引用站点的English/Products分支的实时副本:
来源: /content/we-retail/language-masters/en/products
转出配置:转出配置示例
激活源分支的Products(英语)页面,并观察LiveAction
类生成的日志消息:
16.08.2013 10:53:33.055 *INFO* [Thread-444535] com.adobe.example.msm.ExampleLiveActionFactory$ExampleLiveAction *** ExampleLiveAction has been executed.***
16.08.2013 10:53:33.055 *INFO* [Thread-444535] com.adobe.example.msm.ExampleLiveActionFactory$ExampleLiveAction *** Target node lastModifiedBy property updated: admin ***
AEM使用一组默认的语言和国家/地区代码。
MSM使用存储的语言和国家/地区代码列表来确定与页面语言版本名称关联的国家/地区名称。 您可以根据需要更改列表的以下方面:
en
、de
等)语言列表存储在/libs/wcm/core/resources/languages
节点的下方。 每个子节点表示语言或语言国家/地区:
节点的名称是语言代码(如en
或de
),或language_country代码(如en_us
或de_ch
)。
节点的language
属性存储代码语言的全名。
节点的country
属性存储代码的国家/地区的全名。
当节点名称仅包含语言代码(如en
)时,国家/地区属性为*
,而额外的defaultCountry
属性存储语言国家/地区的代码以指示要使用的国家/地区。
要修改语言,请执行以下操作:
在Web浏览器中打开CRXDE Lite;例如, http://localhost:4502/crx/de
选择/apps
文件夹,然后单击创建,然后单击创建文件夹。
将新文件夹命名为wcm
。
重复上一步骤以创建/apps/wcm/core
文件夹树。 在核心中创建名为resources
的sling:Folder
类型的节点。
右键单击/libs/wcm/core/resources/languages
节点,然后单击复制。
右键单击/apps/wcm/core/resources
文件夹,然后单击粘贴。 根据需要修改子节点。
单击Save All。
单击工具、操作,然后单击Web控制台。 在此控制台中,单击OSGi,然后单击配置。
找到并单击Day CQ WCM语言管理器,将语言列表的值更改为/apps/wcm/core/resources/languages
,然后单击Save。
创建自定义页面资产时,您可能需要考虑新资产是否有资格转出到任何Live Copy。
例如,如果添加了两个新页面属性:
联系电子邮件:
关键可视样式:
然后,您需要确保:
联系电子邮件:
关键可视样式:
页面属性是否受到转出的控制,因此在编辑时是否受取消/恢复继承的控制,将由对话框属性控制:
cq-msm-lockable
适用于触屏优化UI对话框中的项目
将在对话框中创建链链接符号
仅允许在取消继承(链式链接断开)时进行编辑
仅适用于资源的第一个子级
类型: String
值:物业名称(及与物业价值相若 name
);例如,请参阅
/libs/foundation/components/page/cq:dialog/content/items/tabs/items/basic/items/column/items/title/items/title
定义cq-msm-lockable
后,断开/关闭链将通过以下方式与MSM交互:
如果cq-msm-lockable
的值为:
相对 (例如 myProperty
或 ./myProperty
)
cq:propertyInheritanceCancelled
中添加和删除该属性。绝对 (例如, /image
)
cq:LiveSyncCancelled
mixin添加到./image
并将cq:isCancelledForChildren
设置为true
,中断链将取消继承。cq-msm-lockable适用于要编辑的资源的第一个子级别,并且它在任何更深层的上级级别上不起作用,无论该值是定义为绝对值还是相对值。
重新启用继承时,Live Copy页面属性不会自动与源属性同步。 如果需要,您可以手动请求同步。