Tuesday, June 25, 2013

Pagelet wizard - use an Image as a URL

Normally you cannot embed links into URLs with the Pagelet Wizard, and although you can create custom XSL, the PTTP_PAGELET:Pagelet application class expects certain attributes to be treated in certain ways. To get this to work I combined the Image and URL types.

There are several sections where the tags are processed in the Execute method, e.g.


/* Process Image Objects */
&imageNodes = &TransformedDoc.DocumentElement.GetElementsByTagName("PSIMG");


1. So I created a query which just retrieves one row, i.e. on PSOPTIONS.
2. Create a Pagelet using PS Query as a data source.
3. Use custom XSL, so generate normally and then click customise.
4. Modify the XSL to use the new tag, e.g. CASEY.

<xsl:choose>
 <xsl:when test="querydata[position()=2]/text!=''">
  <CASEY target="%PAGELETID">
    <xsl:attribute name="PORTAL">EMPLOYEE</xsl:attribute>
    <xsl:attribute name="CREF">EP_RECV_PO</xsl:attribute>
    <xsl:attribute name="ID">PS_APPROVE_ICN</xsl:attribute>
    <xsl:attribute name="APPEND">?Page=RECV_WPO&Action=U&TargetFrameName=None</xsl:attribute>
  </CASEY>
 </xsl:when>
 <xsl:otherwise> </xsl:otherwise>
</xsl:choose>


4. Modify the Pagelet code to use the new tag, e.g. CASEY.
 
                  /* An error occurred during the formatting process - so just use the NodeValue */
                  &FormattedNodeValue = &NodeValue;
               end-try;
               
            End-For;
         End-If;
         
         /* Casey - Start */
         &linkNodes = &TransformedDoc.DocumentElement.GetElementsByTagName("CASEY");
         If &linkNodes.Len > 0 Then
            For &i = 1 To &linkNodes.Len
               &ParentNode = &linkNodes [&i].ParentNode;
               &removedNode = &linkNodes [&i];
               
               &crefurl = "";
               
               &PortalName = &removedNode.GetAttributeValue("PORTAL");
               &CREFName = &removedNode.GetAttributeValue("CREF");
               
               &imageID = &removedNode.GetAttributeValue("ID");
               &newImageURL = %Response.GetImageURL(@"Image." | &imageID);
               
               If &CREFName <> "" Then
                  If &PortalName <> "" Then
                     &Portal = %Session.GetPortalRegistry();
                     If Not &Portal.Open(&PortalName) Then
                        &Portal = PortalOpen();
                     End-If;
                  Else
                     &Portal = PortalOpen();
                  End-If;
                  &cref = &Portal.FindCREFByName(&CREFName);
                  If &cref <> Null Then
                     Evaluate %This.PSGeneratedLinkType
                     When = %This.PSGENERATEDLINKTYPE_PSP_ABSOLUTE
                        &crefurl = &cref.AbsolutePortalURL;
                        Break;
                     When = %This.PSGENERATEDLINKTYPE_PSC_ABSOLUTE
                        &crefurl = &cref.AbsoluteContentURL;
                        Break;
                     When-Other
                        &crefurl = &cref.RelativeURL;
                     End-Evaluate;
                  End-If;
               End-If;
               
               If &crefurl <> "" Then
                  &s_append = &removedNode.GetAttributeValue("APPEND");
                  
                  /* if the url already has a ?, change a leading ? in the appendstring to an & */
                  If Find("?", &crefurl) > 0 Then
                     If Find("?", &s_append) = 1 Then
                        &s_append = Replace(&s_append, 1, 1, "&");
                     End-If;
                  End-If;
                  
                  &crefurl = &crefurl | &s_append;
                  
                  &replacePosition = &linkNodes [&i].Index;
                  &removedNode = &ParentNode.RemoveChildNode(&linkNodes [&i]);
                  If &ParentNode.ChildNodeCount = 0 Or
                        &ParentNode.ChildNodeCount <= &replacePosition Then
                     &newlinknode = &ParentNode.AddElement("A");
                  Else
                     &newlinknode = &ParentNode.InsertElement("A", &replacePosition);
                  End-If;
                  
                  If &removedNode.GetAttributeValue("target") <> "" Then
                     /* Going to a new target window... */
                     If &removedNode.GetAttributeValue("target") = "%PAGELETID" Then
                        &newlinknode.AddAttribute("target", &ID);
                     Else
                        &newlinknode.AddAttribute("target", &removedNode.GetAttributeValue("target"));
                     End-If;
                     
                     /* Reconstruct the target url to include the _newwin */
                     &crefurl = PSURLToNewWin(&crefurl);
                     
                  Else
                     /* No target specified on link, so take the target property (if exists) */
                     If %This.PSGeneratedLinkTarget <> "" Then
                        &newlinknode.AddAttribute("target", %This.PSGeneratedLinkTarget);
                     End-If;
                     
                  End-If;
                  
                  If &removedNode.GetAttributeValue("class") <> "" Then
                     /* Copy over the class attribute */
                     &newlinknode.AddAttribute("class", &removedNode.GetAttributeValue("class"));
                  End-If;
                  &newlinknode.AddAttribute("href", &crefurl);
                  
                  &newlinknode.AddAttribute("title", &removedNode.NodeValue);
                  &newlinktextnode = &newlinknode.AddText(&removedNode.NodeValue);
                  
                  &newImageNode = &newlinknode.AddElement("IMG");
                  &newImageNode.AddAttribute("src", &newImageURL);
                  &newImageNode.AddAttribute("border", "0");
               Else
                  /* CREF was not found - just write in the text */
                  rem &newlinknode = &ParentNode.AddText(&removedNode.NodeValue);
                  
                  &replacePosition = &linkNodes [&i].Index;
                  &removedNode = &ParentNode.RemoveChildNode(&linkNodes [&i]);
                  If &ParentNode.ChildNodeCount = 0 Or
                        &ParentNode.ChildNodeCount <= &replacePosition Then
                     &newlinknode = &ParentNode.AddText(&removedNode.NodeValue);
                  Else
                     &newlinknode = &ParentNode.InsertText(&removedNode.NodeValue, &replacePosition);
                  End-If;
                  
                  
               End-If;
            End-For;
         End-If;
         
         /* Casey - End */
         
         
         /* Process Registered Links */
         &linkNodes = &TransformedDoc.DocumentElement.GetElementsByTagName("PSREGISTEREDLINK");

Pagelets wizard - view attachments

To allow attachments to be shown via a Pagelet generated by the pagelet wizard
1. Create an IScript, e.g. IScript_GetBISDocs, and register it to a hidden portal content reference.
2. Have a query which identifies the information needed. For example, the PS_BIS_DOCS table stores a Source, e.g. PO, and an Doc Key, contains BU, PO number etc.
3. Create a Pagelet using PS Query as a data source, and define a link for one of the columns, e.g. PO ID, which links to the Content Reference created in step 1.
  • Pass in additional parameters as required, e.g. Business Unit and PO ID.

Here is a link to the document in Skydrive with screen shots of the Pagelet, Query etc.
SkyDrive Doc



Here is the PeopleCode from the IScript.

Function IScript_Get_Docs();
   Local string &strBU = %Request.GetParameter("BUSINESS_UNIT");
   Local string &strPO = %Request.GetParameter("PO_ID");
   Local string &DocSys, &DocName, &strPath, &strFile;
   Local integer &intRtrnCd;
   SetTracePC(0);
   SetTraceSQL(0);
   
   rem Fetch the attachments;
   Get_PO_Docs(&strBU | &strPO, 9999, &DocSys, &DocName);
   
   rem SQLExec("SELECT COMMENTS FROM PSURLDEFN WHERE URL_ID=:1", URL.MY_URL, &strPath);
   If Right(GetEnv("PS_FILEDIR"), 1) <> "\" Then;
      &strPath = GetEnv("PS_FILEDIR") | "\";
   Else;
      &strPath = GetEnv("PS_FILEDIR");
   End-If;
   &strFile = &strPath | &DocName;
   &intRtrnCd = GetAttachment(URL.BIS_GL_BUD_FILE_ATTACH, &DocSys, &strFile);
   
   If FileExists(&strFile, %FilePath_Absolute) Then;
      &intRtrnCd = PutAttachment(URL.FILEDB, &DocName, &strFile);
   End-If;
   
   Local Rowset &attachrs;
   Local integer &row_count;
   Local string &attachrec_name = Record.PSFILE_ATTDET;
   Local string &content_type;
   Local string &attachfile_name = &DocName;
   
   
   &attachrs = CreateRowset(@("Record." | Upper(&attachrec_name)));
   &attachrs.Fill("WHERE ATTACHSYSFILENAME = :1 ORDER BY FILE_SEQ", &attachfile_name);
   
   /*Read the file BLOB from database record and write to response*/
   For &row_count = 1 To &attachrs.ActiveRowCount;
      try
         %Response.WriteBinary(&attachrs(&row_count).GetRecord(@("Record." | Upper(&attachrec_name))).FILE_DATA.Value);
      catch Exception &ex
         %Response.SetContentType("text/plain");
         %Response.Write(MsgGetText(137, 182, "Exception in writing binary file data from database" | " " | &ex.ToString()));
      end-try;
   End-For;
   
   /*%Response.SetHeader("Content-Disposition", "attachment;filename=" | EncodeURL(&attachfile_name));*/
   %Response.SetContentType("application/pdf");
   
   SetTracePC(0);
   SetTraceSQL(0);
   
End-Function;