Loaditemversion

Smartsite 8.0 - ...

De loaditemversion methode kan gebruikt worden om de huidige versie van een item op te halen. Dit is de zogenaamde "-1 versie", welke gelijk is aan de actieve versie indien het item de laatste keer met de status Activeren is opgeslagen, en anders is het de versie die als laatste is opgeslagen met elke andere status. Anders gezegd, het is exact dezelfde versie die wordt geladen indien je in de manager het item zou bewerken.

Als resultaat wordt de versie informatie van het item in xml formaat geretourneerd. Dit is hetzelfde xml formaat dat de manager en de CmsServer gebruiken, als ook het xml formaat waarin de payload voor savecmsitem moet worden aangeboden.

Voordat de versie informatie wordt opgehaald en geretourneerd wordt eerst gecontroleerd of de gebruiker content access heeft op het betreffende item.

Voorbeeld xml

<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://smartsite.nl/namespaces/metadocument/2.0">
<entry>
<nrcontentversion>328147</nrcontentversion>
<nr>103057</nr>
<activationdate xsi:nil="true" />
<adddate>2022-03-04T08:54:05.687</adddate>
<author xsi:nil="true" />
<banner />
<body>&lt;p&gt;Test body with timestamp: 3/4/2022 8:53:58 AM&lt;/p&gt;</body>
<category />
<code>GUID-DA8801C9CDDD4C95BC8663328DA913E0</code>
<commentstate>
<key>-1</key>
</commentstate>
<description xsi:nil="true" />
<editornotes xsi:nil="true" />
<filetype code="XHTML">10</filetype>
<folder>true</folder>
<friendlyname>WebApi-test-item-created-from-scratch-using-savecmsitem</friendlyname>
<friendlynametype />
<gerelateerde_items />
<hiddenchild>false</hiddenchild>
<keywords>
<nr>2164</nr>
<nr>2166</nr>
</keywords>
<logic>&lt;se:itemdata field="Body" /&gt;</logic>
<parent code="GUID-28842F8AA1FD40849894C295B544EFD8">102197</parent>
<searchable>true</searchable>
<seopriority>
<key>0.5</key>
</seopriority>
<showfrom xsi:nil="true" />
<showuntil xsi:nil="true" />
<sortindex>0</sortindex>
<status>11</status>
<title>WebApi test item - created from scratch, using savecmsitem</title>
<userid>1</userid>
<version>-1</version>
</entry>
</data>

Deze xml zou dan bijvoorbeeld weer gebruikt kunnen worden om updates in door te voeren en de xml dan als payload mee te geven aan savecmsitem, in plaats van de payload vanaf scratch op te bouwen. Zie onderstaand C# voorbeeld.

C# voorbeeld

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using System;using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace WebApiConsole
{
    /// <summary>
    /// Console application (.NET 5.0) met voorbeelden hoe de WebApi gebruikt kan worden.
    /// LET OP: de meeste voorbeelden gebruiken item nummers specifiek voor de development site die is gebruikt bij het ontwikkelen van deze voorbeelden.
    /// De console kun je dus nooit zomaar "as is" runnen tegen je eigen site.
    /// De voorbeelden dienen "slechts" ter illustratie hoe e.e.a. aangeroepen dient te worden.
    /// </summary>
    class Program
    {
        private static XNamespace ns = XNamespace.Get("http://smartsite.nl/namespaces/metadocument/2.0");
        private static WebApiOptions options;

        static async Task Main(string[] args)
        {
            // read settings example using json file
            var config = new ConfigurationBuilder()
                .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
                .AddJsonFile("appsettings.json").Build();

            var section = config.GetSection(nameof(WebApiOptions));
            options = section.Get<WebApiOptions>();

            // parent number for adding test items using the WebApi
            int parent = 102197;
            // number of the contenttype for the test items that will be created
            int contentType = 25; // Strict Web page (usually)

            using (HttpClient client = new HttpClient())
            {
// set Authorization header
client.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes($"{options.Username}:{options.Password}"))
);

await CreateAndUpdateItem(client, parent, contentType);
            }
            Console.WriteLine("Done");
        }

        private static async Task<bool> CreateAndUpdateItem(HttpClient client, int parent, int contentType)
        {
            // Create an item "from scratch", specifying (at least) the parent and contenttype (both required)
            XElement data = new XElement(ns + "data",
                new XElement(ns + "entry",
                    new XElement(ns + "parent", parent),
                    new XElement(ns + "contenttype", contentType),
                    new XElement(ns + "title", "WebApi test item - created from scratch, using savecmsitem"),
                    new XElement(ns + "body", $"Test body with timestamp: {DateTime.Now}")
                )
            );

            Console.WriteLine($"Creating item 'from scratch' using method 'savecmsitem', parent = {parent}");
            // call the savecmsitem method, which will automatically swith to AddItem mode when the xml does not contain an itemnumber
            var httpContent = new StringContent(data.ToString());
            var response = await client.PostAsync($"{options.Url}/savecmsitem", httpContent);
            ReportResponse(response);

            if (response.IsSuccessStatusCode)
            {
                // update the item
                string itemNr = response.Content.ReadAsStringAsync().Result;
                if (Int32.TryParse(itemNr, out int itemNumber))
                {
                    // laod the item version
                    Console.WriteLine($"Item {itemNumber} created, loading item version for this item");
                    string versionXml = await client.GetStringAsync($"{options.Url}/loaditemversion?itemnumber={itemNumber}");

                  // use XDocument to read the xml
                    XDocument cmsItem = XDocument.Parse(versionXml);
                    XElement cmsEntry = cmsItem.Root.Element(ns + "entry");

                    // update a number of fields
                    {
                        // update description
                        cmsEntry.SetElementValue(ns + "description", $"Omschrijving (updated: {DateTime.Now})");
                        // update keywords
                        XElement element = cmsEntry.Element(ns + "keywords");
                        if (element != null)
                        {
                            // remove existing terms
                            element.RemoveNodes();
                            // add nr element for each keyword
                            element.Add(
                                new XElement(ns + "nr", 2164),
                                new XElement(ns + "nr", 70730),
                                new XElement(ns + "nr", 70822)
                            );
                        }

                        // update gerelateerde_items field (content relation)
                        element = cmsEntry.Element(ns + "gerelateerde_items");
                        if (element != null)
                        {
                            // remove existing item relations
                            element.RemoveNodes();
                            // add nr element for each item relation
                            element.Add(
                                new XElement(ns + "nr", 68028),
                                new XElement(ns + "nr", 67662)
                            );
                        }
                    }

                    // call SaveCmsItem method to update the item
                    Console.WriteLine($"Update item {itemNumber} using savecmsitem");
                    string requestUrl = $"{options.Url}/savecmsitem";
                    httpContent = new StringContent(cmsItem.ToString());
                    response = await client.PostAsync(requestUrl, httpContent);
                    ReportResponse(response);
                }
            }
            return true;
        }

        private static void ReportResponse(HttpResponseMessage response)
        {
            if (response.IsSuccessStatusCode)
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("Item(s) updated.");
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.Red;
                string msg = response.Content.ReadAsStringAsync().Result;
                Console.WriteLine($"Item(s) could not be updated: {msg}");
            }
            Console.ResetColor();
        }
    }
}

Bovenstaand voorbeeld is een complete console application. Om deze werkend te krijgen zijn nog twee dingen nodig, een configuratie class (WebApiOptions) en een application settings bestand (appsettings.json). Zie voorbeelden hieronder.

WebApiOptions class

public class WebApiOptions
{
public string Url { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}

appsettings.json

{
"WebApiOptions":
{
"Url": "http://localhost/mgr/webapi.net",
"Username": "gebruikersnaam",
"Password": "wachtwoord"
}
}

WebApi macro voorbeeld

<se:if expression="!request.isaimrequest()">
  <se:webapi username="gebruikersnaam" password="wachtwoord" method="loaditemversion"
itemnumber="82171" save="versionxml" />
<pre>
{string. xmlencode(buffer.get(versionxml,default=''))}
</pre>
</se:if>

Met behulp van de webapi macro kan loaditemversion ook aangeroepen worden. In dit voorbeeld wordt slechts de xml getoond in een pre element.