• RedDot CMS Blog
  • 28.12.2016
  • EN

rdb: RedDot CMS API – or – RQL in a nutshell – Part 2

There are several ways of accessing the RedDot CMS API. You can use RenderTags or use the RedDot Query Language, also known as “RQL”. This article explains how to use RQL for advanced requirements like event controlled RQL, remote RQL execution, binding RQL to workflows and much more.

Have you already seen this article RQL in a nutshell of the brilliant Manuel Schnitger? Yes? Well, at some point you’ll have questions which are not answered in the formerly mentioned article.
Therefore Manuel is back with this new article full of useful goodness that will help you when creating RQL-based applications.

Event controlled RQL

Usually an RQL plugin is called via a link in SmartEdit or SmartTree and will be executed in the second you click on the link…..so user interaction is required.  But what has to be done if you want the plugin/application to be executed when a specific event (e.g.: page released) in the workflow is reached? Let’s  do it step-by-step.
In this sample the goal is that you trigger an RQL application via the workflow. The action that is performed is not important….just the steps that result into performing the action.

Step #1: Creating a user defined job in the Server Manager

a) Go to the Server Manager > User defined jobs and click on "Create user defined job" in the action menu

Figure 1:Server Manager – Administer user defined jobs

b) in the upcoming dialogue enter a name for this job (e.g.: myNewJob)

Figure #2: Add a name for the job

c) in the next dialogue activate the checkbox "call event controlled" and deactivate the other one (important!)

Figure 3: Activating the option “Event controlled”

d) in the next dialogue choose the option "Open URL" and enter the url to your RQL application

Figure 4: Adding the URL of your application

Step #2: Assigning the user defined job in the project

a) Enter the SmartTree
b) create a workflow
c) click on "Page released" and then on "add reaction"  (of course jobs can also be triggered when the workflow level is different to "page released" )

Figure 5: Small sample workflow

c) In the opening dialogue click on "Start job" and choose the user defined job you just created in the Server Manager.

Figure 6: Workflow triggers a user defined job (RQL application)

Ready and good to go!!! Now the RQL application will be triggerred each time a page that is connected to this specific list is being released.

Usually when you wish to start a job – when a specific step in the workflow is reached you also want to let the RQL application do something with the page in workflow. But then there is this:

How do you know the GUID of the page in the workflow?

And how can you transfer the GUID of the page into your application? It’s very simple: Just add another reaction to the workflow!
Click on the action "page released"  then on "add reation" in the action menu and choose the reaction "Write workflow XML".

You will be asked for a location (folder) where the workflow xml file(s) shall be placed (see figure below) after closing the dialogue every time a page is released two things happen. First the workflow xml file will be written (one file for each page & event) under the specified path and after that the RQL application is triggered.
What you have to do next in your application is: Reading out the page guid and using it in your application.

Figure 7: Path for the workflow xml files

Sample code how to extract the GUID of a page and the GUID of the project the page is part of

Set oXml = Server.CreateObject("Microsoft.XMLDOM")
Set rootNode = oXml.documentElement
if rootNode.hasChildNodes() Then
  for Each e in rootNode.childNodes
    if e.nodename = "PAGEGUID" then
      sPageGuid = e.childNodes(0).text
      response.write "<br>PageGuid: " & sPageGuid & "<br>"
    end if
    if e.nodename = "PROJECTGUID" then
      sProjectGuid = e.childNodes(0).text
      response.write "<br>ProjectGuid: " & sProjectGuid & "<br>"
    end if
end if

Please be aware of the fact that -if you call an RQL application this way- you don’t have any session variables such as login guid or the session key. So you’ll have to write some RQL code for the login procedure and the validation (= connecting to a project). (If you should face issues with these steps… give us some feedback.)

EmptyBuffer – How to delete text element content using RQL

If you want to delete something using RQL you write something like <PAGE action="delete"
or <USER action="delete" or something similar depending on the thing you wish to delete.
This works well whenever you want to delete the "object" itself; it does not work when you’d like to delete the content (Text) of an object (Textelement).  In order to delete a text from a text element or from  a standardfield you have to save the so called "Empty buffer". (Of course the empty buffer can delete much more than just the content of a text element or standardfield.)

Sample for deleting the text of a text element:

sValue = session("EmptyBuffer")
"<IODATA format=""1"" loginguid=""" & sLoginGUID & """ sessionkey=""" & sSessionKey & """>"&_
"<ELT reddotcacheguid="""" action=""save"" guid=""" & sEltGuid & """ pageid="""" id="""" index="""" type=""" & sType & """>" & sValue & "</ELT>"&_

Q: What is the empty buffer?
A: It’s just a hash tag followed by the session key of the current user.
So this: response.write session("emptybuffer") and this: response.write "#" & session(sessionkey) result in the same output.

Remote RQL – Triggering the RedDot CMS API via external applications

Generally plugins or other RQL based applications are placed on the editorial server meaning the server where the Open Text Management Server software is installed. And normally plugins are called via a link or RQL applications are triggered by the workflow. But what if you have a server where a specific application runs and when you want to execute RQL statements triggered by this application?

Example: There is an application that writes product related information into an XML file and you want to create a page on the editorial server based on this information.

What you could do is a) writing a small directory listener that notices when a new file is being written b) read out the relevant data and c) use the RQL bridge to communicate with the editorial server.
Ok, let’s do it step-by-step:

Step #1: Create a file called "RqlBridge.asp"

using this code and place it in a folder called "remoterql" under the plugins directory (obviously you have to create this folder ;-) on the editorial server.

<%@ Language=VBScript %>
<%server.ScriptTimeout = 5 %>
function sendXML(XMLString)
  set objData = server.CreateObject("RDCMSASP.RdPageData")
  sendXML = objData.ServerExecuteXml(XMLString, sErrors)end function
XMLString = request("sXmlData")
if XMLString <> "" then
   sReturn = sendXML(XMLString)
Response.Write sReturn
end if

As we can see, the function sendXML just executes the RQL statement. The function itself is called in the second block of the code. In the code below we then can see how the communication between the editorial server and the "other" server is managed.

Step #2:  Create a file based on this code and place it on the "other" server.

As I’ve added some comments in the code to make it more clear what exactly happens.
First I just get the Login Guid. You’ll now ask: "How the hell did he get the login guid…? This file is supposed to be on the "other" server where no session variables are available…!" Right, I tested the RqlBridge on just ONE server (my editorial server), but the functionality also works when there are two servers.

sLoginGUID = Session("LoginGUID")
'Then the RQL statement is written in the variable "xmlString".
xmlString = "<IODATA loginguid=""" & sLoginGUID & """>"&_
"<PROJECTS action=""list""/>"&_
'Here we call the file "RqlBridge.asp" (on our editorial server)
'and transfer the RQL statement (xmlString) as the content of
'the parameter sXmlData.
'As written above the RqlBridge is just being used to execute the RQL.
'So as a result of this call we receive the server response from the editorial server.
RqlRequest = GetServerAnswer("http://localhost/cms/plugins/remoterql/rqlbridge.asp?sXmlData=" & xmlString)
Response.Write "<br/>Server Response:" & server.htmlencode(RqlRequest) & "<br/>"
' The function GetServerAnswer just calls an URL and returns the response.
' This is not related to the Management Server but is more a general functionality.
Function GetServerAnswer(sUrl)
   Dim objHTTP, sServerAnswer
   Set objHTTP = Server.CreateObject("WinHttp.WinHttpRequest.5.1")
   objHTTP.SetTimeouts 0, 3000, 2000, 5000
   objHTTP.open "GET", sUrl, false
   if err.Number<>0 then
   end if
   on error goto 0
end function

Ready! We are now able to create calls on server A that will be executed on server B. I don’t know if this is helpful for much people but at least I wanted to point out this option.

RedDot CMS date de- and encoding: Working with dates

The next thing you might try and read out is the creation date of a page or perhaps the appearance schedule for a page. You will notice that the dates are not really readable as they are just floating point number.
So if you would like to display a date in a way that people can read it, you have to encode the date. And if you would like to save a date…. of course you have to decode it previously ;-)
The code below demonstrates both directions. If you create a plugin based on this code you will see how a serial date will be converted into a floating point number and vice versa.

  'converts a serial date into a floating point number that can be stored into the database
  mydate = "11/11/2010"
  set RQLObject = Server.CreateObject("RDCMSAsp.RdPageData")
  mydate = RqlObject.EncodeDate(myDate)
  response.write mydate & "<br>"
  mydate = "30493"
  set RQLObject = Server.CreateObject("RDCMSAsp.RdPageData")
  mydate = RqlObject.DecodeDate(myDate)
  response.write mydate & "<br>"
  'converts a date (floating point number) into a serial date ....that can be understood by humans ; - )

If you would like to learn more about converting date values in RedDot CMS, check out this article with code examples.

sendXML function

In order to enhance the overview of the code in your applications you might want to have an area where you just place the RQL functions and another area where you implement the logic. But even the execution of the RQL statements can be excluded in a seperate function. Of course this is not that much but at least we save a few lines of code.

function sendXML (XMLString)
set objData = server.CreateObject("RDCMSASP.RdPageData")
     sendXML = objData.ServerExecuteXml(XMLString, sErrors)
     if sErrors <> "" then
        response.write "Errors occured: " & sErrors & chr(13) & XMLString & "<br>"
    end if
 objData = NULL
end function

If you find any errors or have questions, please just leave a comment and I’ll try to help. If you’re interested in more RQL related articles then….right…send us some feedback.

Have fun with RQL!