首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Tridion和REL:在页面的PublishedUrl属性中更新页面文件名

Tridion和REL:在页面的PublishedUrl属性中更新页面文件名
EN

Stack Overflow用户
提问于 2013-01-09 15:55:02
回答 2查看 258关注 0票数 4

我们有一个页面的网址需要本地化/翻译的要求。我们现有的机制依赖于实际发布的url来通过oData检索页面。用一个简化的例子来说明:我们在前端有一些逻辑,它接受请求url (它没有文件扩展名,附加一个.html扩展名,例如:

代码语言:javascript
运行
复制
/my-awesome-path/my-awesome-page

现在变成了

代码语言:javascript
运行
复制
/my-awesome-path/my-awesome-page.html

然后,该逻辑使用以下查询从oData中拉出页面

代码语言:javascript
运行
复制
/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那样将我引向死胡同?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-11 12:48:15

遵循上面Nuno评论中的观点,我决定不使用自定义部署程序,并使用事件系统的2个事件订阅解决了这个问题。在页面发布时,我首先本地化页面,从本地化的链接元数据组件中获取本地化的文件名,然后保存页面。然后,在随后的事件中,我只需取消页面的本地化。以下是我的工作代码:

代码语言:javascript
运行
复制
[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;
    }
}
票数 3
EN

Stack Overflow用户

发布于 2013-01-09 16:41:02

也许是另一种选择:

存储本地化的URL对页面有一个额外的元数据字段,为发布的页面保留相同的物理URL。

我明白你的要求是避免子页面的本地化,我喜欢在wordpress中输入全球URL工作方式的方式,例如:

/mysite/%postname%/

在SDL Tridion中构建类似的东西会很酷,其中内容标题可以被提取出来并在内容URL中使用。

无论哪种方式,如果你必须编写一个接受“友好URL”并查找实际URL的系统,我认为这将是非常简单的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14230571

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档