I understand (at least) two ways to implement Page Metadata:
Create a schema of type 'Embeddable'. Add it in e.g. 'Home Page' tab 'Metadata'. When "Use this Page Schema as Metadata Schema" it is used and can be filled in. JSON generated for Page like this ('metadata' is filled name):
Create a schema type 'Metadata' and select it on a specific page. Then Page JSON is something like this:
Question-1: How to implement strong name for Metadata Schema?
Both options comes in Razor view back as dictionary e.a. @Model.Meta["publishdate"]
You have to check fields before usage.
Question-2: What is the way to go to collect metadata at page level?
- General (embedded) metadata schema is added to each page schema. Works OOTB.
- Add metadata to components and extract that to page level. How to do that?
- Add metadata to Structure Group and get that in metadata with the pages. Some field should be added for Page as metadata it self.
UPDATE-1: CustomPageModel.cs should do proper mapping to any meta fields. Below the code and values I tried for mapping. Example use 2 fields and 1 embedded schema to catch.
[Serializable]
[SemanticEntity(EntityName = "artikelPage", Vocab = "SDL_CORE")]
[SemanticEntity(EntityName = "mymoduleArtikelPage")]
[SemanticEntity(EntityName = "pageArtikelPage")]
[SemanticEntity(EntityName = "mymodule:Page:ArtikelPage")]
[SemanticEntity(EntityName = "regionSchema")]
[SemanticEntity(EntityName = "ArtikelPage")]
[SemanticEntity(EntityName = "metadata")]
[SemanticEntity(EntityName = "Metadata")]
[SemanticEntity(EntityName = "artikelPage")]
public class CustomPageModel : PageModel
{
public CustomPageModel() : base() { }
public CustomPageModel(string id) : base(id) { }
[SemanticProperty("test1")]
public string Test1 { get; set; }
[SemanticProperty("test2")]
public DateTime? Test2 { get; set; }
[SemanticProperty("publishdate")]
public DateTime? PublishDate { get; set; }
//[SemanticProperty("metadata")]
[SemanticProperty("paginaMetadata")]
public PaginaMetadata PaginaMetadata { get; set; }
}
The tab Source of the 'Artikel Page' Page schema.
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="uuid:3feadbb7-8212-405d-9ac5-d212711e5a2f" xmlns:tcmi="http://www.tridion.com/ContentManager/5.0/Instance" elementFormDefault="qualified" targetNamespace="uuid:3feadbb7-8212-405d-9ac5-d212711e5a2f">
<xsd:import namespace="http://www.tridion.com/ContentManager/5.0/Instance" schemaLocation="cm_xml_inst.xsd"></xsd:import>
<xsd:include schemaLocation="tcm:105-418027-8"></xsd:include>
<xsd:annotation>
<xsd:appinfo>
<tcm:Labels xmlns:tcm="http://www.tridion.com/ContentManager/5.0">
<tcm:Label ElementName="test1" Metadata="true">Test1</tcm:Label>
<tcm:Label ElementName="paginaMetadata" Metadata="true">Pagina metadata velden</tcm:Label>
<tcm:Label ElementName="test2" Metadata="true">Test 2</tcm:Label>
</tcm:Labels>
</xsd:appinfo>
</xsd:annotation>
<xsd:element name="Metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="test1" minOccurs="0" maxOccurs="1" type="xsd:normalizedString">
<xsd:annotation>
<xsd:appinfo>
<ExtensionXml xmlns="http://www.tridion.com/ContentManager/5.0"></ExtensionXml>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="paginaMetadata" minOccurs="0" maxOccurs="1" type="PaginaMetadata">
<xsd:annotation>
<xsd:appinfo>
<ExtensionXml xmlns="http://www.tridion.com/ContentManager/5.0"></ExtensionXml>
<tcm:EmbeddedSchema xmlns:tcm="http://www.tridion.com/ContentManager/5.0" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="tcm:105-418027-8" xlink:title="PaginaMetadata"></tcm:EmbeddedSchema>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="test2" minOccurs="0" maxOccurs="1" type="xsd:dateTime">
<xsd:annotation>
<xsd:appinfo>
<ExtensionXml xmlns="http://www.tridion.com/ContentManager/5.0"></ExtensionXml>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
UPDATE-2: BinaryData\tcm-99\system\mappings\schemas.json
"Id": 417532,
"RootElement": "ArtikelPage",
"Fields": [
{
"Name": "test1",
"Path": "/Metadata/test1",
"IsMultiValue": false,
"Semantics": [
{
"Prefix": "tri",
"Entity": "ArtikelPage",
"Property": "test1"
}
],
"Fields": [],
"FieldType": 0
},
Expected should work with value: [SemanticEntity(EntityName = "ArtikelPage")]
Workaround is 'workers' functions in the CustomPageModel and call when needed. More logical to the class instead of view(s) e.g..:
public bool IsValidField(string field)
{
return this.Meta.ContainsKey(field) && this.Meta[field] != null;
}
public string GetFieldValue(string field)
{ ...
}
UPDATE-3 : It works. Added in tab 'Meta Design' of schema 'Article Page' this schema 'PaginaMetadata'. Its has Root Element name 'PaginaMetadata' and had to use it for the SemanticEntity. Props are filled now in CustomPageModel.
[Serializable]
[SemanticEntity(EntityName = "PaginaMetadata")]
public class CustomPageModel : PageModel
{
public CustomPageModel() : base() { }
public CustomPageModel(string id) : base(id) { }
public DateTime? PublishDate { get; set; }
public string Publisher { get; set; }
...
}