Content Iterator

The Content Iterator

Overview

The Content Iterator (IBO) is our Mura approach to the Iterator Pattern. It's meant to provide a simpler way to hook into what Mura has to offer when it comes to accessing the capabilities of the content bean (example: save, delete, extended attributes). The iterator in a way works like a query result set but in a more object oriented fashion. Instead of working with simple string data that would come from a query record you would instead get a content bean with record information as well as content bean baked in functionality.

It's important to note that the Iterator when called upon does not have any beans loaded within it initially. Instead beans are created upon request (example: using the next() method). This approach keeps the iterator from getting bloated with beans which could easily promote memory issues.

Below are a few use cases that will help you get an understanding on how the Mura Iterator generally works.

Flow Diagram

Below is how the Iterator works when it comes to retrieving data. As you will find the Iterator is hooked directly to the cache, so if you have caching on it will utilize it accordingly.

Example Usage

ContentBean.getKidsIterator()

This would be how you would get all underlying kids that are associated to a given page and display each child's information to the screen.

<!--- Read out an existing node from the default site.---> 
<cfset content=application.contentManager.getActiveContentByFilename('blog','default')>

<!--- Pull out a content iterator of the nodes child content (all underlying pages within a given node).--->
<cfset it=content.getKidsIterator()>

<!--- The number of Items to be listed is determined by the content.getNextN() value. Its default is 10. --->
<cfset it.setPage(1)>

<!--- You can also set the start row instead of setting a page number. --->
<cfset it.setStartRow(1)>
<cfloop from="1" to="#it.pageCount()#" index="p">
<cfset it.setPage(p)>
<cfoutput><h2>Page #p#</h2></cfoutput>
<!--- Iterate throught the child content.
The it.hasNext() will return true until the page length
as determined by the content.getNextN() has been reached --->
<cfloop condition="it.hasNext()"> <!--- The it.next() method returns a new contentNavBean. It acts as a facade to data into the wrapped query while digging into the full bean when needed. --->
<cfset sub1=it.next()>
<cfoutput>
#it.currentIndex()#:#sub1.getMenuTitle()#</br>
</cfoutput>
</cfloop> </cfloop>

FeedBean.getIterator()

You can also get the same iterator from local content indexes:

<!--- Pull a index by its name with the new
feedManager.readByName() method. This example is pulling a
local index named "documents" from the default site.--->
<cfset feed=application.feedManager.readByName('documents','default')>
<cfset it=feed.getIterator()>
<h2><cfoutput>#feed.getName()#</cfoutput></h2>
<cfif it.recordCount()>
<!--- Iterate throught the child content --->
<cfloop condition="it.hasNext()">
<cfset subContent=it.next()>
<cfoutput>
#it.currentIndex()#: #subContent.getMenutitle()#</br>
</cfoutput>
</cfloop>
</cfif>
Wrap an Existing Query

You can also wrap any existing query that contains contentID and siteID or contentHistID and siteID and start iterating.

<cfquery name="rsExample">
select content,siteID from tcontent where .....
</cfquery>
<cfset it=application.serviceFactory.getBean("contentIterator")>
<cfset it.setQuery(rsExample)/>
<!--- Now Iterate and pull attributes that aren't in the query --->
<cfloop condition="it.hasNext()">
<cfset content=it.next()>
<cfoutput>
#it.currentIndex()#: #content.getMenutitle()# - #content.getCustomVar()#</br>
</cfoutput>
You Can Event Start with a List
<cfset it=application.serviceFactory.getBean("contentIterator")>
<cfset it.BuildQueryFromList("423AC11B-3DB8-49EF-B411A2FB008CAB1E,423AC11B-3DB8-49EF-B411A2FB008CABAS","default")>
<!--- Now Iterate --->
<cfloop condition="it.hasNext()">
<cfset content=it.next()>
<cfoutput>
#it.currentIndex()#: #content.getMenutitle()# - #content.getCustomVar()#</br>
</cfoutput>