我们有一个页面的网址需要本地化/翻译的要求。我们现有的机制依赖于实际发布的url来通过oData检索页面。用一个简化的例子来说明:我们在前端有一些逻辑,它接受请求url (它没有文件扩展名,附加一个.html扩展名,例如:
/my-awesome-path/my-awesome-page
现在变成了
/my-awesome-path/my-awesome-page.html
然后,该逻辑使用以下查询从oData中拉出页面
/odata.svc/Pages?$filter=url eq '/my-awesome-path/my-awesome-page.html'
我们有更多的逻辑来解析这个SEO友好的url,并获得MVC控制器的功能参数和其他什么,但这在这里是不相关的。
我们的要求是,我们不能本地化页面来给它一个翻译后的url,因为这将意味着整个页面不能在父web发布中管理。
要获得指向页面文件名的本地化路径,我们只需本地化SGs。困难在于页面文件名。在页面的元数据上,我们有一个链接的“可本地化的元数据”组件,该组件具有一个用于提供本地化页面文件名的字段。
我们想要做的是在发布/部署过程中更新页面的URL属性,用这个链接的元数据组件中的本地化页面文件名更新页面的已发布url (假设我们可以在发布开始到提交部署之间的任何阶段访问本地化文件名字段的值)。
我尝试过通过一个自定义的解析器来做这件事,但是,在这个级别上,page.PublishedUrl属性似乎已经由CM建立了,并且不能被覆盖。因此,更新page.FileName属性不会做任何有用的事情。
我还尝试将Broker DB的页面表中的URL列直接更新为不同的名称,看起来一切都在继续,包括页面的动态链接和取消发布。显然,编写存储扩展或部署扩展来通过jdbc直接更新数据库是不可接受的。
以下是我正在考虑的选项: 1)尝试部署扩展并使用Tridion API更新url属性2)尝试编写执行url替换逻辑的自定义渲染器,而不实际更新代理中的url。我不赞成这样做,因为每次都需要请求时间处理。
我的问题是:更新页面url属性最合适的方法是什么?使用Tridion API编写自定义部署程序来更新URL属性会不会像Resolver那样将我引向死胡同?
发布于 2013-01-11 12:48:15
遵循上面Nuno评论中的观点,我决定不使用自定义部署程序,并使用事件系统的2个事件订阅解决了这个问题。在页面发布时,我首先本地化页面,从本地化的链接元数据组件中获取本地化的文件名,然后保存页面。然后,在随后的事件中,我只需取消页面的本地化。以下是我的工作代码:
[TcmExtension("Publish or Unpublish Events")]
public class PublishOrUnpublishEvents : TcmExtension
{
public PublishOrUnpublishEvents()
{
EventSystem.Subscribe<Page, PublishEventArgs>(SetLocalizedPageFileName, EventPhases.Initiated);
EventSystem.Subscribe<Page, SetPublishStateEventArgs>(UnlocalizePageOncePublished, EventPhases.Initiated);
}
public void SetLocalizedPageFileName(Page page, PublishEventArgs args, EventPhases phase)
{
string localFilename = GetLocalilizedFileNameFromPageMetadata(page);
if (!string.IsNullOrEmpty(localFilename))
{
page.Localize();
if (page.TryCheckOut())
{
page.FileName = localFilename;
page.Save(true);
}
}
}
public void UnlocalizePageOncePublished(Page page, SetPublishStateEventArgs args, EventPhases phase)
{
string localFilename = GetLocalilizedFileNameFromPageMetadata(page);
if (!string.IsNullOrEmpty(localFilename))
page.UnLocalize();
}
private string GetLocalilizedFileNameFromPageMetadata(Page page)
{
string localFilename = string.Empty;
if (page.Metadata != null)
{
ItemFields fields = new ItemFields(page.Metadata, page.MetadataSchema);
if (fields.Contains("LocalizableMeta"))
{
ComponentLinkField localMetaField = fields["LocalizableMeta"] as ComponentLinkField;
Component component = localMetaField.Value;
ItemFields compFields = new ItemFields(component.Content, component.Schema);
if (compFields.Contains("LocalizedPageFilename"))
{
SingleLineTextField fileNameTextField = compFields["LocalizedPageFilename"] as SingleLineTextField;
localFilename = fileNameTextField.Value;
}
}
}
return localFilename;
}
}
发布于 2013-01-09 16:41:02
也许是另一种选择:
存储本地化的URL对页面有一个额外的元数据字段,为发布的页面保留相同的物理URL。
我明白你的要求是避免子页面的本地化,我喜欢在wordpress中输入全球URL工作方式的方式,例如:
/mysite/%postname%
/
在SDL Tridion中构建类似的东西会很酷,其中内容标题可以被提取出来并在内容URL中使用。
无论哪种方式,如果你必须编写一个接受“友好URL”并查找实际URL的系统,我认为这将是非常简单的。
https://stackoverflow.com/questions/14230571
复制相似问题