tag:help-archives.hannonhill.com,2010-02-09:/discussions/web-services/4-integrating-3rd-party-information-into-cascade-pagesCascade CMS: Discussion 2018-10-18T20:35:58Ztag:help-archives.hannonhill.com,2010-02-09:Comment/22152432010-07-09T19:47:58Z2010-07-09T19:48:02ZIntegrating 3rd party information into Cascade pages<div><p>I accomplished this using a combination of Feed Blocks (an XML
file external to Cascade) and a data definition. Within Cascade, I
have a data definition that has some search criteria (prefix: YOG,
number: 100) and a block (the Feed Block for our course schedule).
XSL returns course listings for just those courses that match the
search criteria. Doesn't use Web Services, but that's one way to
accomplish it.</p></div>Eric L. Eppstag:help-archives.hannonhill.com,2010-02-09:Comment/22152432010-07-12T22:11:33Z2010-11-08T22:43:21ZIntegrating 3rd party information into Cascade pages<div><p>Hi Eric,</p>
<p>I'm interested in learning more about how you solved the problem.<br />
</p>
<p>Do I understand correctly that your course schedule is being stored in external XML files? How do you keep the info up to date? Do you have a batch that recreates those XML files periodically? ( this approach would work for well us )</p>
<p>In Cascade, you have defined a Data Definition for one course? Is all the course information stored in a single XML file?</p>
<p>Then you created a block to display a single course? I assume you had to write the XSLT which loops through the XML file and displays only the requested courses. How are parameters passed to the block?</p>
<p>BTW, any chance you are using the Banner ERP?</p>
<p>Thanks,</p>
<p>Jeff</p></div>jephperro2tag:help-archives.hannonhill.com,2010-02-09:Comment/22152432010-07-13T13:17:20Z2010-07-13T13:17:20ZIntegrating 3rd party information into Cascade pages<div><p>Yes, we are using Banner, and the XML file is created daily from
Banner (using COBOL). Here's a sample of the XML:</p>
<pre>
<code> <schedule>
<year name="2010">
<semester display="no" enddate="20100513" name="Spring" startdate="20100111">
<subject name="ACC">
<subjectstring>Accounting</subjectstring>
<course name="Basic Accounting">
<number>100</number>
<iai />
<outlinepath />
<preq />
<crn name="60086">
<startdate>20100111</startdate>
<enddate>20100513</enddate>
<sec>N</sec>
<fee>10</fee>
<meeting>
<credits>4</credits>
<day>MW</day>
<starttime>16:00</starttime>
<endtime>17:40</endtime>
<location>2M9A</location>
<instructor>CC. West</instructor>
</meeting>
<seatsavailable>13</seatsavailable>
<totalseats>25</totalseats>
<sec8week>no</sec8week>
<comment />
</crn>
<appliedprogram>
<name>Associate in Applied Science</name>
<field>Office &amp; Admin Serv:Admin Asst</field>
<number>023</number>
<method>Major Field Requirement</method>
</appliedprogram>
<appliedprogram>
<name>Associate in Applied Science</name>
<field>Office &amp; Admin Serv: Medical</field>
<number>024</number>
<method>Major Field Requirement</method>
</appliedprogram>
<appliedprogram>
<name>Associate in Applied Science</name>
<field>Office &amp; Admin Serv: Legal</field>
<number>026</number>
<method>Major Field Requirement</method>
</appliedprogram>
<appliedprogram>
<name>Certificate</name>
<field>Early Childhood Ed, Adv</field>
<number>F16</number>
<method>Related Field Requirement</method>
</appliedprogram>
</course>
......</code>
</pre>
<p>There's a few different ways we use this, but the most flexible
is a data definition I created to search for specific courses. I
use it to create a standard page that includes whatever page
content and then a list of courses that match that search criteria.
Here's the data definition XML:</p>
<pre>
<code><system-data-structure>
<text wysiwyg="true" identifier="content" label="Page Content"/>
<group identifier="search" label="Schedule Info">
<asset type="block" identifier="blockID" label="BlockName" required="true"/>
<group identifier="searchCrit" label="Search Criteria" multiple="true">
<text identifier="prefix" label="Prefix (e.g. ACC)" maxlength="3"/>
<text identifier="number" label="Number (e.g. 101)" maxlength="3"/>
<text identifier="section" label="Section (e.g. TI)" maxlength="2"/>
<text identifier="program" label="Applicable Program (e.g. 020)"/>
<text identifier="title" label="Course Title"/>
<text identifier="instructor" label="Instructor Name"/>
</group>
</group>
</system-data-structure></code>
</pre>
<p>The block applied in the data definition is the XML Feed Block
for the file above. And, finally, here is the XSLT applied to the
page:</p>
<pre>
<code><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="utf-8" omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:copy-of select="system-data-structure/content"/>
<xsl:apply-templates select="system-data-structure/search/blockID/content/schedule/year/semester[not(@display)]"/>
</xsl:template>
<xsl:template match="semester">
<xsl:call-template name="countSearchCrit">
<xsl:with-param name="searchCritCount" select="count(/system-data-structure/search/searchCrit)"/>
<xsl:with-param name="iterCount">1</xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template match="*" name="countSearchCrit">
<xsl:param name="searchCritCount"/>
<xsl:param name="iterCount"/>
<xsl:variable name="countResults" select="count(subject[contains(@name,/system-data-structure/search/searchCrit[number($iterCount)]/prefix)]/course[contains(number,/system-data-structure/search/searchCrit[number($iterCount)]/number) and contains(@name,/system-data-structure/search/searchCrit[number($iterCount)]/title) and contains(appliedprogram/number,/system-data-structure/search/searchCrit[number($iterCount)]/program)]/crn[not(omitlisting) and contains(sec,/system-data-structure/search/searchCrit[number($iterCount)]/section)])"/>
<xsl:choose>
<xsl:when test="$searchCritCount > $iterCount and $countResults = 0">
<xsl:call-template name="countSearchCrit">
<xsl:with-param name="searchCritCount" select="$searchCritCount"/>
<xsl:with-param name="iterCount"><xsl:value-of select="number($iterCount)+1"/></xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:when test="$searchCritCount = $iterCount and $countResults = 0">
<h2><xsl:value-of select="@name"/><xsl:text> </xsl:text><xsl:value-of select="../@name"/><xsl:text> </xsl:text>Course Offerings</h2>
<p>There are no course offerings for this search criteria this semester. You may find other courses in <a href="/students/schedules/">the full SVCC schedule</a>.</p>
</xsl:when>
<xsl:otherwise>
<h2><xsl:value-of select="@name"/><xsl:text> </xsl:text><xsl:value-of select="../@name"/><xsl:text> </xsl:text>Course Offerings</h2>
<table cellspacing="0" class="courseListing">
<thead>
<tr>
<th id="crn">CRN</th>
<th id="course">Course</th>
<th id="title">Title</th>
<th id="section">Section</th>
<th id="credits">Hrs</th>
<th id="day">Day</th>
<th id="time">Time</th>
<th id="room">Room</th>
<th id="instructor">Instructor</th>
<th id="seats">Seats</th>
<th id="fee">Fee</th>
</tr>
</thead>
<tbody>
<xsl:call-template name="matchSearchCrit">
<xsl:with-param name="searchCritCount" select="count(/system-data-structure/search/searchCrit)"/>
<xsl:with-param name="iterCount">1</xsl:with-param>
</xsl:call-template>
</tbody>
</table>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="*" name="matchSearchCrit">
<xsl:param name="searchCritCount"/>
<xsl:param name="iterCount"/>
<xsl:apply-templates select="subject[contains(@name,/system-data-structure/search/searchCrit[number($iterCount)]/prefix)]/course[contains(number,/system-data-structure/search/searchCrit[number($iterCount)]/number) and contains(@name,/system-data-structure/search/searchCrit[number($iterCount)]/title) and contains(appliedprogram/number,/system-data-structure/search/searchCrit[number($iterCount)]/program)]/crn[not(omitlisting) and contains(sec,/system-data-structure/search/searchCrit[number($iterCount)]/section)]"/>
<xsl:if test="$searchCritCount > $iterCount">
<xsl:call-template name="matchSearchCrit">
<xsl:with-param name="searchCritCount" select="$searchCritCount"/>
<xsl:with-param name="iterCount"><xsl:value-of select="number($iterCount)+1"/></xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="crn">
<xsl:apply-templates select="meeting"><xsl:with-param name="parentpos"><xsl:value-of select="position()"/></xsl:with-param></xsl:apply-templates>
<xsl:if test="string(comment)">
<tr>
<th colspan="2" id="comments">Comments:</th>
<td colspan="9" headers="course comments"><xsl:value-of select="comment"/></td>
</tr>
</xsl:if>
</xsl:template>
<xsl:template match="meeting">
<tr>
<td headers="crn"><xsl:if test="position() = 1"><xsl:value-of select="../@name"/></xsl:if></td>
<td headers="course"><xsl:value-of select="../../../@name"/>&#160;<xsl:value-of select="../../number"/></td>
<td headers="title"><xsl:value-of select="../../@name"/></td>
<td headers="section"><xsl:if test="position() = 1"><xsl:value-of select="../sec"/></xsl:if></td>
<td headers="credits"><xsl:if test="position() = 1"><xsl:value-of select="credits"/></xsl:if></td>
<td headers="day"><xsl:value-of select="day"/></td>
<td headers="time">
<xsl:if test="string(endtime)">
<xsl:choose>
<xsl:when test="substring-before(starttime,':') > 12"><xsl:value-of select="substring-before(starttime,':') - 12"/>:<xsl:value-of select="substring-after(starttime,':')"/></xsl:when>
<xsl:otherwise><xsl:value-of select="starttime"/></xsl:otherwise>
</xsl:choose>
<xsl:text>-</xsl:text>
<xsl:choose>
<xsl:when test="substring-before(endtime,':') > 12"><xsl:value-of select="substring-before(endtime,':') - 12"/>:<xsl:value-of select="substring-after(endtime,':')"/></xsl:when>
<xsl:otherwise><xsl:value-of select="endtime"/></xsl:otherwise>
</xsl:choose>
</xsl:if>
</td>
<td headers="room"><xsl:value-of select="location"/></td>
<td headers="instructor"><xsl:value-of select="instructor"/></td>
<td headers="seats"><xsl:if test="position() = 1"><xsl:value-of select="../seatsavailable"/></xsl:if></td>
<td headers="fee"><xsl:if test="position() = 1 and string(../fee)">$<xsl:value-of select="../fee"/></xsl:if></td>
</tr>
</xsl:template>
</xsl:stylesheet></code>
</pre>
<p>Now, if I could assign a Content Type to a Publish Set (<a href=
"http://hannonhill.uservoice.com/forums/52559-cascade-ideas/suggestions/904681-add-content-types-for-publish-sets">http://hannonhill.uservoice.com/forums/52559-cascade-ideas/suggesti...</a>),
I could have all files sitewide that have course schedule
information auto-publish daily. (shameless plug for votes)</p></div>Eric L. Eppstag:help-archives.hannonhill.com,2010-02-09:Comment/22152432010-07-13T13:37:09Z2010-07-13T13:37:09ZIntegrating 3rd party information into Cascade pages<div><p>Another application (this one is more relevant to Web Services)
is that we have course listings by department. So we'll have a file
named "ACC" to display all the accounting courses. That page has a
data definition with a block chooser set to the XML Feed Block:</p>
<pre>
<code><system-data-structure>
<group identifier="blockchooser" label="block" multiple="false">
<asset type="block" identifier="blockID" multiple="true" label="BlockName" required="true"/>
</group>
</system-data-structure></code>
</pre>
<p>The DEFAULT region of the page, then, has an index block
assigned that indexes the current page (including the XML content),
and the XSLT searches the attached Feed Block for courses that
match the page's System Name.</p>
<p>This works great, except when a new course prefix is added. I
then have to go in and create a new page for that prefix. This is
easy enough--when I'm notified that a new course prefix
<em>has</em> been added. I'm currently looking at Web Services to
search the XML file and create those pages daily.</p></div>Eric L. Epps