Pregunta

Is it possible to extract information of a SDL Tridion page including the contents associated to it in a xml format.

I am expecting something similar to this:

   <page name="mypagename">
     <page id="xxxxx"/>
     <template name="abc" id="123">
        <container name="xyz">
          <content name="asd" id="123">
           <Path="" \>
          </content>
        </container>
     </template>
    </page>

The technology stack is Tridion 2011 and Java.

I am a newbie to Tridion, so little detailed answer would be greatly helpful.

¿Fue útil?

Solución

Depending what you actually need, there are MUCH simpler ways of doing this, but I use the following TBB class written in C# build a page XML divided into Content Regions based on Component Template Metadata

class GetPageXML : TemplateBase
    {
        public override void Transform(Engine engine, Package package)
        {
            Initialize(engine, package);
            Logger.Debug("This will get the full page XML");
            Item pageItem = m_Package.GetByType(ContentType.Page);

            Page currentPage = GetPage();

            m_Engine.PublishingContext.RenderContext.ContextVariables.Add("CURRENT_PAGE", currentPage);


            XmlDocument pageXml = pageItem.GetAsXmlDocument();
            foreach (XmlNode cpNode in pageXml.SelectNodes("/tcm:Page/tcm:Data/tcm:ComponentPresentations/tcm:ComponentPresentation", NSManager))
            {
                TcmUri componentURI = new TcmUri(cpNode.SelectSingleNode("tcm:Component/@xlink:href", NSManager).Value);
                TcmUri componentTemplateURI = new TcmUri(cpNode.SelectSingleNode("tcm:ComponentTemplate/@xlink:href", NSManager).Value);

                //Render the componentPresentation
                XmlNode cpRenderElement = pageXml.CreateElement("tcm", "RenderedComponentPresentation", "http://www.tridion.com/ContentManager/5.0");
                XmlAttribute attNamespace = pageXml.CreateAttribute("xmlns:tcdl");
                attNamespace.Value = "http://www.tridion.com/ContentDelivery/5.3/TCDL";
                cpRenderElement.Attributes.Append(attNamespace);


                if (m_Engine.PublishingContext.RenderContext.ContextVariables.Contains("ORDINAL_POSITION"))
                {
                    int ordinalPosition = ((int)m_Engine.PublishingContext.RenderContext.ContextVariables["ORDINAL_POSITION"]) + 1;
                    m_Engine.PublishingContext.RenderContext.ContextVariables["ORDINAL_POSITION"] = ordinalPosition;
                //    m_Engine.PublishingContext.RenderContext.ContextVariables["ORDINAL_POSITION"] = 0;
                }
                else
                {
                    m_Engine.PublishingContext.RenderContext.ContextVariables.Add("ORDINAL_POSITION", 0);
                }


                //Get the metadata from the CT
                ComponentTemplate componentTemplate = (ComponentTemplate)m_Engine.GetObject(componentTemplateURI);
                String metadataXmlString = "";
                String cpRegionName = "";
                if (componentTemplate.Metadata != null)
                {
                    metadataXmlString = componentTemplate.Metadata.OuterXml;
                    XmlNode cpRegionNode = componentTemplate.Metadata.SelectSingleNode("//*[local-name()='region']");
                    if (cpRegionNode != null)
                    {
                        cpRegionName = "_" + cpRegionNode.InnerText;
                    }
                }
                cpNode.SelectSingleNode("tcm:ComponentTemplate", NSManager).InnerXml = metadataXmlString;



                String REGIONAL_POSITION = "REGIONAL_POSITION" + cpRegionName;
                if (m_Engine.PublishingContext.RenderContext.ContextVariables.Contains(REGIONAL_POSITION))
                {
                    int regionalPosition = ((int)m_Engine.PublishingContext.RenderContext.ContextVariables[REGIONAL_POSITION]) + 1;
                    m_Engine.PublishingContext.RenderContext.ContextVariables[REGIONAL_POSITION] = regionalPosition;
                    //    m_Engine.PublishingContext.RenderContext.ContextVariables["ORDINAL_POSITION"] = 0;
                }
                else
                {
                    m_Engine.PublishingContext.RenderContext.ContextVariables.Add(REGIONAL_POSITION, 0);
                }



                DateTime cpRenderStart = DateTime.Now;
                string contentCP = m_Engine.RenderComponentPresentation(componentURI, componentTemplateURI);

                DateTime cpRenderEnd = DateTime.Now;
                TimeSpan cpRenderTime = cpRenderEnd.Subtract(cpRenderStart);

                XmlAttribute attCPRenderTime = pageXml.CreateAttribute("RenderTime");
                attCPRenderTime.Value = String.Format("{0:0000}", cpRenderTime.TotalMilliseconds) + " milliseconds";
                cpNode.Attributes.Append(attCPRenderTime);


                if (m_Engine.RenderMode != RenderMode.Publish)
                {
                    //Remove the '&' symbols created for linking in previewmode
                    contentCP = contentCP.Replace("&", "");

                }

                try
                {
                    cpRenderElement.InnerXml = contentCP;
                }
                catch (Exception e)
                {
                    cpRenderElement.InnerXml = "Malformed XML in the output:" + e.Message;// +"<!--" + contentCP + "-->";
                }
                cpNode.AppendChild(cpRenderElement);



                Component component = (Component)m_Engine.GetObject(componentURI);
                XmlAttribute attComponentRevisionDate = pageXml.CreateAttribute("ModifiedOn");
                attComponentRevisionDate.Value = component.RevisionDate.ToString("yyyy-MM-dd HH:mm:ss tt");
                cpNode.Attributes.Append(attComponentRevisionDate);



                //Get the metadata from the Component

                metadataXmlString = "";
                if (component.Metadata != null)
                {
                    metadataXmlString = component.Metadata.OuterXml;
                }

                cpNode.SelectSingleNode("tcm:Component", NSManager).InnerXml = metadataXmlString;
            }



            //Add the rendered/published time
            XmlAttribute attRenderTime = pageXml.CreateAttribute("RenderedAt");
            attRenderTime.Value = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss tt");
            pageXml.DocumentElement.Attributes.Append(attRenderTime);

            //Add PublishInfo
            //Get the PublishTransaction

            PublishTransaction pubTrans = GetPublishTransaction(engine);

            if (pubTrans != null)
            {
                XmlElement nodePublisher = pageXml.CreateElement("Publisher");
                XmlElement nodePublisherName = pageXml.CreateElement("name");
                XmlElement nodePublisherId = pageXml.CreateElement("id");
                XmlElement nodePublisherDescription = pageXml.CreateElement("description");

                nodePublisherName.InnerText = pubTrans.Creator.Title;
                nodePublisher.AppendChild(nodePublisherName);

                nodePublisherId.InnerText = pubTrans.Creator.Id.ToString();
                nodePublisher.AppendChild(nodePublisherId);

                nodePublisherDescription.InnerText = pubTrans.Creator.Description;
                nodePublisher.AppendChild(nodePublisherDescription);

                pageXml.DocumentElement.AppendChild(nodePublisher);
            }

            //Add the target info
            if (engine.PublishingContext.PublicationTarget != null)
            {
                XmlElement nodePublicationTarget = engine.PublishingContext.PublicationTarget.ToXml();
                XmlNode nodePubs = nodePublicationTarget.SelectSingleNode("/tcm:PublicationTarget/tcm:Data/tcm:Publications", NSManager);
                nodePubs.ParentNode.RemoveChild(nodePubs);


                pageXml.DocumentElement.AppendChild(pageXml.ImportNode(nodePublicationTarget, true));
            }





            //Add the Page Modified time
            ModificationInfo modInfo = GetNewestModificationDateFromPageXml(pageXml);

            XmlAttribute attContentModifiedTime = pageXml.CreateAttribute("ContentLastModifiedOn");
            attContentModifiedTime.Value = modInfo.ModificationDate.ToString("yyyy-MM-dd HH:mm:ss tt");
            pageXml.DocumentElement.Attributes.Append(attContentModifiedTime);

            XmlAttribute attLastModifiedItem = pageXml.CreateAttribute("LastModifiedItemURI");
            attLastModifiedItem.Value = modInfo.ItemURI.ToString();
            pageXml.DocumentElement.Attributes.Append(attLastModifiedItem);

            XmlAttribute attLastModifiedTitle = pageXml.CreateAttribute("LastModifiedItemTitle");
            attLastModifiedTitle.Value = modInfo.ItemTitle;
            pageXml.DocumentElement.Attributes.Append(attLastModifiedTitle);




            //Add PageTemplate Properties
            XmlNode nodePageTemplate = pageXml.SelectSingleNode("/tcm:Page/tcm:Data/tcm:PageTemplate", NSManager);
            TcmUri uriPageTemplate = new TcmUri(nodePageTemplate.Attributes["href", "http://www.w3.org/1999/xlink"].Value);
            XmlElement pageTemplateXml = engine.GetObject(uriPageTemplate).ToXml(XmlSections.Data);
            nodePageTemplate.ParentNode.ReplaceChild(pageXml.ImportNode(pageTemplateXml, true), nodePageTemplate);

            //Add the publication properties
            XmlNode nodePublication = pageXml.SelectSingleNode("/tcm:Page/tcm:Context/tcm:Publication", NSManager);
            TcmUri uriPublication = new TcmUri(nodePublication.Attributes["href", "http://www.w3.org/1999/xlink"].Value);
            XmlElement publicationXml = engine.GetObject(uriPublication).ToXml(XmlSections.Data);
            nodePublication.ParentNode.ReplaceChild(pageXml.ImportNode(publicationXml,true), nodePublication);
            m_Package.PushItem("UrbanCherryPageFrameWork", m_Package.CreateXmlDocumentItem(ContentType.Xml,pageXml));
        }

You could stop at the line XmlDocument pageXml = pageItem.GetAsXmlDocument();and simply push that value into the package and call it Output.

Alternatively take a look at the DD4T templates, as they output a standard XML structure for pages also.

Otros consejos

You're actually asking for a quite difficult thing to answer, because of Tridion's flexible data model.

There's a few things known for sure:

  • There are Pages
    • Pages have properties like Title, ID, URL, Publication Id, Version, Creation Date, Published Date, etc
  • Pages may have Component Presentations
    • Component Presentations have content in them

The content of a component (or set of components) is most likely what you are searching for, since this is the data you want to display on your website. Components are stored as XML in the Tridion Content Manager, and transformed by a template when publishing. The XML schema that the component uses is defined by the implementer (therefore all implementations are likely to use different schemas) and the template that transforms that component is also defined by the implementer - and therefore all implementations are likely to have different outputs.

So, if you want to use Tridion XML to build up a website on the delivery tier, you need to:

  1. Define the schemas for your content according to your website requirements
  2. Define a template that will publish your content as XML to the delivery tier

(I am simplifying a lot here - don't underestimate the work required in defining a proper content model for any given organization)

Chris gives you a good example on how to push XML to the delivery tier. Frameworks like DD4T give you this template "for free" - but you still need to design the schemas yourself.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top