- 7.x
- 9.x
- 10.x
- 11.x
- Clear cache for specific page instead of entire project.
- In SmartTree, select page, Action Menu, Clear Page Cache
- In SmartEdit, open page, right click, plugins in context menu, Clear Page Cache
The most common need to use an include directive is to include/reuse a common piece of component of the site, such as header, footer and advertisement.
When using a media or image element in place of actual file name, the generated path contains ., which is invalid pathing by default unless enabled in IIS. The other issue with leading . in pathing is one cannot use that in #include virtual.
' Code in CMS template <!--#include virtual="<%med_transformer_asp%>"--> ' Generated code in SmartEdit or Page Preview. Invalid code <!--#include virtual="../ImageCache/521E5D7461214F71889B2A99C6CAD3F4/514EAAB6BEBB4F86B85AF45DB2A09374/TR/transformer.asp"-->
' Code in CMS template <!--#include virtual="<%anc_transformer_asp%>"--> ' Generated code in SmartEdit or Page Preview. Invalid code <!--#include virtual="./PreviewHandler.ashx?Action=Preview&Mode=0&blahblahblahblah"-->
When using #include file directive, the pathing uses \, CMS publish pathing as /. Though this is a minor issue since both syntax are acceptable.
' desired syntax <!-- #include file="common\header.htm" --> ' generated syntax <!-- #include file="common/header.htm" -->
The biggest issue with #include file in CMS is that the path returned is incorrect
' Code in CMS template <!--#include file="<%med_transformer_asp%>"--> ' Generated code in SmartEdit or Page Preview. <!--#include file="../ImageCache/521E5D7461214F71889B2A99C6CAD3F4/514EAAB6BEBB4F86B85AF45DB2A09374/TR/transformer.asp"--> ' This maps to ' ASP\ReddotTemp\ImageCache\521E5D7461214F71889B2A99C6CAD3F4\514EAAB6BEBB4F86B85AF45DB2A09374\TR\transformer.asp ' Instead of ' ASP\ImageCache\521E5D7461214F71889B2A99C6CAD3F4\514EAAB6BEBB4F86B85AF45DB2A09374\TR\transformer.asp
' Code in CMS template <!--#include file="<%anc_transformer_asp%>"--> ' Generated code in SmartEdit or Page Preview. <!--#include file="./PreviewHandler.ashx?Action=Preview&Mode=0&blahblahblahblah"--> ' This maps to ' ASP\ReddotTemp\BC498EE1113D41F7AC877F3D5BD0738E\PreviewHandler.ashx?Action=Preview&Mode=0&blahblahblahblah ' The path is correct, but the file gets deleted as soon as it is generated and displayed.
One can work around the pathing issue with manual path correction
<!IoRangePreExecute> ' Code in CMS template <!--#include file="../<%med_transformer_asp%>"--> <!/IoRangePreExecute> ' Generated code during publication mode, invalid code, the file is published ' to the asp folder on the web server. The asp folder is not on the CMS ' server, so preexecution is trying to use a file that doesn't exist <!--#include file="../asp/transformer.asp"-->
If you simply want to use include to include a static file, like header. In publishing mode, use #include, which uses a anchor placeholder to reference the header page. When not publishing, use the header container placeholder, which references the header page.
<reddot:cms> <if> <query valuea="Context:CurrentRenderMode" operator="==" valueb="Int:2"> <htmltext> <!--#include file="<%anc_header%>"--> </htmltext> </query> <query type="else"> <htmltext> <%con_header%> </htmltext> </query> </if> </reddot:cms>
If you want to include an asp library and use the library during SmartEdit, Page Preview, and Publishing, reference the absolute path via #include virtual directive
<!IoRangePreExecute> ' Code in CMS template <!--#include virtual="/cms/plugins/asplib/transform.asp"--> <!/IoRangePreExecute>
There was COM using VB, but susceptible to server timeout in large operations and cannot cancel the server side operation once it has started.
Set objIO = CreateObject("RDCMSASP.RdPageData") objIO.XmlServerClassName = "RDCMSServer.XmlServer" xmlData = "<IODATA sessionkey=""" & session("sessionkey") & """ loginguid=""" & session("loginguid") & """><PAGE action=""load"" guid=""" & strTreeGuid & """/></IODATA>" xmlData = objIO.ServerExecuteXml (xmlData, sError) ' parse that xmlData
There was COM using C#. It is a cleaner language, but one has to relax COM security for this to work. Also, it is susceptible to server timeout in large operations and cannot cancel the server side operation once it has started.
// look up how to transfer asp session to aspx session // Basically, asp page loop through all sessions and submit them to aspx // which then save the received sessions into aspx sessions string _LoginGuid = HttpContext.Current.Session["projectguid"].ToString(); string _SessionKey = HttpContext.Current.Session["sessionkey"].ToString(); string _PageGuid = HttpContext.Current.Session["treeguid"].ToString(); object objRQL; object[] RQL_Server = { "RDCMSServer.XmlServer" }; objRQL.GetType().InvokeMember("XmlServerClassName", BindingFlags.SetProperty, null, objRQL, RQL_Server); object[] RQL_Command = { string.Format("<IODATA sessionkey=\"{0}\" loginguid=\"{1}\"><PAGE action=\"load\" guid=\"{2}\"/></IODATA>", _LoginGuid, _SessionKey, _PageGuid) }; object retObj = objRQL.GetType().InvokeMember("ServerExecuteXml", BindingFlags.InvokeMethod, null, objRQL, RQL_Command); if (retObj != null) { // parse that retObj }
There was web service using C#. It has the benefit of a cleaner language and no need for extra configuration in COM security, but the plugin will be competing with Management Server for communication bandwidth because many core components are also using the web service. Also, it is susceptible to server timeout in large operations and cannot cancel the server side operation once it has started.
// look up how to transfer asp session to aspx session // Basically, asp page loop through all sessions and submit them to aspx // which then save the received sessions into aspx sessions string _LoginGuid = HttpContext.Current.Session["projectguid"].ToString(); string _SessionKey = HttpContext.Current.Session["sessionkey"].ToString(); string _PageGuid = HttpContext.Current.Session["treeguid"].ToString(); // RqlService is a class manually generated using Visual Stuio by pointing to the web service URL RqlService RqlServiceObj = new RqlService(); string RQL_Command = string.Format("<IODATA sessionkey=\"{0}\" loginguid=\"{1}\"><PAGE action=\"load\" guid=\"{2}\"/></IODATA>", _LoginGuid, _SessionKey, _PageGuid); object retObj = RqlServiceObj.ExecuteString(RQL_Command); if (retObj != null) { // parse that retObj }
Some people advanced to AJAX against an ASP connector or the web service because these plugins are easy to write, troubleshoot, and no longer susceptible to server timeout in large operations and run away server side operation once it has started. It is best practice to use ASP connector instead of web service because ASP connector do not compete with core component for communication bandwidth and it is compatible with Management Server 6.x, 7.x, 9.x, 10.x, whereas the web service is only available beginning at 7.x, changes location at 10.x and 11.x. Hence plugins written against the web service is not all version compatible automatically.
// AJAX ASP var strRQLXML = padRQLXML('<PAGE action="load" guid="<%= session("treeguid") %>">'); $.post('rqlaction.asp', { rqlxml: strRQLXML }, function(data){ // parse $(data) }); function padRQLXML(innerRQLXML) { return '<IODATA loginguid="<%= session("loginguid") %>" sessionkey="<%= session("sessionkey") %>">' + innerRQLXML + '</IODATA>'; }
<?xml version="1.0" encoding="utf-8" ?> <% ' action.asp Response.ContentType = "text/xml" Dim objIO 'Declare the objects Dim xmlData, sError, retXml set objIO = Server.CreateObject("RDCMSASP.RdPageData") objIO.XmlServerClassName = "RDCMSServer.XmlServer" xmlData = Request.Form("rqlxml") xmlData = objIO.ServerExecuteXml (xmlData, sError) Set objIO = Nothing If sError <> "" Then retXml = "<ERROR>" & sError & "</ERROR>" Else retXml = xmlData End If Response.Write(retXml) %>
// AJAX web service var SOAPMessage = ''; SOAPMessage += '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cms="http://reddot.de/cms/webservices/navigation/1_1"><soapenv:Header/><soapenv:Body><cms:ExecuteString><cms:command>'; SOAPMessage += padRQLXML(InnerRQL); SOAPMessage += '</cms:command></cms:ExecuteString></soapenv:Body></soapenv:Envelope>'; $.ajax({ type: 'POST', url: '/CMS/Navigation/Services/RQLService.asmx', data: SOAPMessage, contentType: 'text/xml; charset=utf-8', dataType: 'xml', beforeSend: function(xhr) { xhr.setRequestHeader('SOAPAction', '"http://reddot.de/cms/webservices/navigation/1_1/ExecuteString"'); }, success: function (data) { // parse $(data) }, error: function (message) { //alert(message); } }); function padRQLXML(InnerRQL) { var Rql = '<IODATA loginguid="<%= session("loginguid") %>" sessionkey="<%= session("sessionkey") %>"><![CDATA[' + InnerRQL + ']]></IODATA>'; return Rql; }
Management Server is at version 11.x. One has to change the COM object name in ASP in order for VB plugins to continue to work, and this should only be a short term fix because as stated in the RQL manual, COM will be obsolete and web service will be the sole future. One also has to change the web service URL and SOAP format in order for AJAX web service plugins to continue to work in 11.x. The question: how to write a plugin that is 7.x to 11.x compatible automatically? Answer: use a AJAX RQL connector library at https://github.com/jhuangsoftware/j-rql-connector
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script> <script type="text/javascript" src="Rqlconnector.js"></script> <script type="text/javascript"> var LoginGuid = '<%= session("loginguid") %>'; var SessionKey = '<%= session("sessionkey") %>'; var RqlConnectorObj = new RqlConnector(LoginGuid, SessionKey); var strRQLXML = '<PAGE action="load" guid="' + PageGuid + '"/>'; RqlConnectorObj.SendRql(strRQLXML, false, function(data){ // parse $(data) }); </script>
' quick and short term change to make VB to continue to work Set objIO = CreateObject("OTWSMS.AspLayer.PageData") xmlData = "<IODATA sessionkey=""" & session("sessionkey") & """ loginguid=""" & session("loginguid") & """><PAGE action=""load"" guid=""" & strTreeGuid & """/></IODATA>" xmlData = objIO.ServerExecuteXml (xmlData, sError) ' parse that xmlData
The AJAX RQL Connector is meant to be used on something small to medium things, like to automatically send some RQLs whenever a user does something in SmartEdit or Page Preview, or to send some RQLs based on user inputs in a plugin interface. Ideally, all plugins should use this connector library over other RQL libraries (Java, C#, PHP?) because a plugin should be plug-and-play with no dependency on any other external installations or configurations.
Does it mean other RQL libraries (Java, C#, PHP?) are bad? No. They are still useful for large implementations, where a plugin should really be called an application integration. However, please be aware that support for RQL libraries (Java, C#, PHP?) falls outside of OpenText support because in event of error, one has to proof the fault is at RQL level, not the library that encapsulates the RQL.
There has been many confusions over when to use a list element or a container element. For Example, I want to have a slider module on my home page.
The flexslider has the following HTML code:
<div class="flexslider" id="myflexslider"> <ul class="slides"> <li> <img src="slide1.jpg" /> </li> <li> <img src="slide2.jpg" /> </li> <li> <img src="slide3.jpg" /> </li> <li> <img src="slide4.jpg" /> </li> </ul> </div> <script type="text/javascript" charset="utf-8"> $('#myflexslider').flexslider(); </script>
Each slide is a page containing a slide image. Then a list placeholder is used to pull in images.
<!-- flexslider content class --> <!IoRangeRedDotMode> <div class="alert-reddot <!IoRangeNoEditMode>alert-error<!/IoRangeNoEditMode><!IoRangeRedDotEditOnly>alert-success<!/IoRangeRedDotEditOnly>"> <div><!IoRedDotOpenPage> [<!IoRangeNoEditMode>Open to Edit<!/IoRangeNoEditMode><!IoRangeRedDotEditOnly>Close to Save<!/IoRangeRedDotEditOnly> Page]</div> <!IoRangeRedDotEditOnly> <div><!IoRedDot_lst_slides> [Manage Slides]</div> <!/IoRangeRedDotEditOnly> </div> <!/IoRangeRedDotMode> <div class="flexslider" id="myflexslider"> <ul class="slides"> <!IoRangeList> <li> <!-- <%lst_slides%> --> <!IoRedDot_img_slide><%img_slide%> </li> <!/IoRangeList> </ul> </div> <script type="text/javascript" charset="utf-8"> $('#myflexslider').flexslider(); </script>
This is a sub-optimal method because
Each slide is a page containing a slide image. Then a container placeholder is used to contain the pages.
<!-- flexslider content class --> <!IoRangeRedDotMode> <div class="alert-reddot <!IoRangeNoEditMode>alert-error<!/IoRangeNoEditMode><!IoRangeRedDotEditOnly>alert-success<!/IoRangeRedDotEditOnly>"> <div><!IoRedDotOpenPage> [<!IoRangeNoEditMode>Open to Edit<!/IoRangeNoEditMode><!IoRangeRedDotEditOnly>Close to Save<!/IoRangeRedDotEditOnly> Page]</div> <!IoRangeRedDotEditOnly> <div><!IoRedDot_con_slides> [Manage Slides]</div> <!/IoRangeRedDotEditOnly> </div> <!/IoRangeRedDotMode> <div class="flexslider" id="myflexslider"> <ul class="slides"> <%con_slides%> </ul> </div> <script type="text/javascript" charset="utf-8"> $('#myflexslider').flexslider(); </script>
<!-- flexslider slide content class --> <li> <!IoRedDotOpenPage><!IoRedDot_img_slide><%img_slide%> </li>
I hope the following blockmark usage examples would help clarify the many blockmarks and associated usages.
<!-- do not need conditional, no output if empty --> <%stf_teaser%> <!IoRangeConditional> <div class="orange"> <%stf_teaser%> </div> <!/IoRangeConditional> <!IoRangeRedDotMode> <!-- this is shown in SmartEdit, either open or closed <div class="reddot-area"> <!IoRedDotOpenPage> <!IoRangeNoEditMode> <!-- this is shown when this section is closed in SmartEdit --> <div class="reddot-closed">[Open to Edit]</div> <!/IoRangeNoEditMode> <!IoRangeRedDotEditOnly> <!-- this is shown when this section is open in SmartEdit --> <div class="reddot-opened">[Close to Edit]</div> <!/IoRangeRedDotEditOnly> </div> <!/IoRangeRedDotMode> <!-- if you want to produce repeatable HTML with variable content, and the links go to the DIFFERENT sub folder <ul> <li><a href="/products/link1.htm">link 1</a></li> <li><a href="/news/link2.htm">link 2</a></li> <li><a href="/about-us/link3.htm">link 3</a></li> </ul> --> <ul> <!IoRangeDynLink> <li><%anc_dyn_links%></li> <!/IoRangeDynLink> </ul> <!-- if you want to produce repeatable HTML with variable content, and the links go to the SAME sub folder <ul> <li><a href="/products/link1.htm">link 1</a></li> <li><a href="/products/link2.htm">link 2</a></li> <li><a href="/products/link3.htm">link 3</a></li> </ul> --> <ul> <!IoRangeList> <li><%lst_links%></li> <!/IoRangeList> </ul>
Recently, I have had the great joy of working on some Facebook events integration. The issue was that the requests were sent one at a time. Facebook batch request was the answer.
The existing code base is C#. I can use the popular C# Facebook SDK at http://csharpsdk.org/, but it might be overly complex for the project.
So I wrote this little C# Facebook Batch Request connector: https://github.com/jhuangsoftware/FacebookBatchRequest
Sure. Extend current project to covert returned JSON to HTML. Alternatively, use the current connector as part of your project, which actually converts JSON to HTML
<%@ Import Namespace="FacebookBatchRequestLib" %> <%@ Import Namespace="System.Collections.Generic" %> <% FacebookBatchRequest FBBatchRequestObj = new FacebookBatchRequest("XYZ|XYZ"); FBBatchRequestObj.AddBatchUrl(RequestMethod.GET, "something1/events?access_token=XYZ|XYZ&fields=name,description,start_time,end_time,location,id&since=2013-03-08&limit=15"); FBBatchRequestObj.AddBatchUrl(RequestMethod.GET, "something2/events?access_token=XYZ|XYZ&fields=name,description,start_time,end_time,location,id&since=2013-03-08&limit=15"); ListRetJSONs = FBBatchRequestObj.Send(); %>
Just remember to drop FacebookBatchRequestLib.dll into the bin folder
Included in the GitHub project. Check it out.
It is recommended to use projects with HTML5 code after 10.1 SP2 HF18 (Build 10.1.2.391) because the Telerik/RadEditor text editor now also support HTML5 code and would not strip them out.
<reddot:cms> <foreach itemname="ArrayItem" object="Escape:Text(Test1,Test2).Split(Escape:Text(,))"> <htmltext> <h2><%!! Store:ArrayItem !!%></h2> </htmltext> </foreach> </reddot:cms>