How to display a list of blocks if they contain specific text

geoff's Avatar

geoff

03 Mar, 2015 05:02 PM

Hi folks,

I need create a report that lists the names of blocks if those blocks include specific text. Any chance someone's already done this? Want to share your script? Or can you point me to a layperson's Velocity tutorial that'll help? (I know virtually nothing about transforming XML; I normally just try to back-engineer chunks of other people's scripts as needed. ;)

So, at a basic level, the format should:
-- look for blocks in every system-folder, including any nested folders, and... -- look for "product_name" text in the "system-block/system-data-structure/external_content" node, and... -- if "product_name" exists in that node, display the name of the block, preceded by the folder name/path in which the block resides.

Hope that's enough to go on. Thanks in advance for any help.

  1. 1 Posted by Wing Ming Chan on 03 Mar, 2015 05:40 PM

    Wing Ming Chan's Avatar

    Hi,

    I am not sure if this is doable using simple Velocity code. I believe that even the new query API cannot do what you want. If this is really the case, then you have two options left: direct query of the database, or use web services.

    Wing

  2. 2 Posted by geoff on 03 Mar, 2015 06:24 PM

    geoff's Avatar

    Okay. Good to know sooner than later.
    But for what it's worth, I have the following code which may be partially relevant to my request (I withheld it initially to avoid any potential confusion), but obviously, several things about it aren't relevant (e.g., years). Perhaps it triggers ideas and sheds light on the realm of possibility?

    #set ( $years = ["2005", "2006"] )
    
    #foreach ( $year in $years )
        #set ( $pages = $_XPathTool.selectNodes($contentRoot, "/system-index-block/system-block[contains(path,'${year}')][system-data-structure[contains(wysiwyg,'${year}')][contains(goals,'${year}')]]") )
        <h1>${year}</h1>
        <ul>
            #foreach ( $page in $pages )
               <li>
                ${_EscapeTool.xml($page.getChild("title").value)}
               </li>
            #end
        </ul>
    #end
    
  3. 3 Posted by Wing Ming Chan on 03 Mar, 2015 07:35 PM

    Wing Ming Chan's Avatar

    I thought you were interested in blocks existing in various sites, associated with various data definitions. But if you just want to grab all data definition blocks within a single site, using the same data definition, then your code should work, assuming of course that all blocks can be indexed (i.e., not hidden in some non-indexable folders).

    Wing

  4. 4 Posted by geoff on 03 Mar, 2015 07:57 PM

    geoff's Avatar

    Good, I'm heading down the right path. Now I just need to figure out which parts of that code I need to replace/modify to address the criteria in my initial post.

    I'll try to remember to post a final, working version when I figure it out... unless someone else beats me to it... which I'd absolutely welcome. :)

  5. 5 Posted by geoff on 03 Mar, 2015 08:03 PM

    geoff's Avatar

    ...and just to clarify, you're right that I'm targeting a single site.

  6. 6 Posted by Ryan Griffith on 03 Mar, 2015 08:36 PM

    Ryan Griffith's Avatar

    Hi,

    Depending on the number of Blocks we're talking about, you could also use the Query API to grab all Block assets and loop over them to see if they are: a) structured data blocks and b) contain the field and text you need to search on.

    Consider the following as a starting point:

    #set ( $query = $_.query() )
    #set($query = $query.byMetadataSet("Basic"))
    #set($query = $query.includePages(false))
    #set($query = $query.includeFiles(false))
    #set($query = $query.includeBlocks(true))
    #set($query = $query.includeFolders(false))
    #set($query = $query.includeSymlinks(false))
    #set($query = $query.siteName("www.example.com"))
    #set ($blocks = $query.execute())
    #if ($blocks.size() > 0)
        <ul>
        #foreach ($block in $blocks)
            #set ($ddPath = $block.dataDefinitionPath)
    
            ## We only want SD Blocks with a specific Data Definition.
            #if (!$_PropertyTool.isNull($ddPath) && $ddPath == "Data-Definition/Path")
                #set ($sdField = $block.getStructuredDataNode("external_content"))
                
                ## We only want SD Blocks with a specific field that contains a certain value.
                #if (!$_PropertyTool.isNull($sdField) && $sdField.contains("product_name"))
                    <li>${block.name} (${block.parentFolder.path})</li>
                #end
            #end
        #end
        </ul>
    #end
    
  7. 7 Posted by geoff on 03 Mar, 2015 09:57 PM

    geoff's Avatar

    Thanks for the additional option, Ryan. I'll return after I learn a thing or two about what I'm doing. ;)

  8. 8 Posted by Ryan Griffith on 04 Mar, 2015 01:54 PM

    Ryan Griffith's Avatar

    Not a problem at all, geoff.

    The solution you us really depends on your needs. If you would like to generate this report within Cascade Server, a Format would be the way to go. To add to that, whether you want to use an Index Block or the Locator Tool depends on a few factors:

    • Are any of your Blocks set to not be indexable? If so, an Index Block won't work so well.
    • Do you have more than 500 Blocks? If so, the Query API will cap the report at 500.
    • How often are you planning to run the report? Because Index Blocks are cached they can sometimes be quicker; however, the size of the Index Block may negate the caching, making the Locator Tool a better choice.

    As always, please don't hesitate to ask questions!

  9. Ryan Griffith closed this discussion on 11 Mar, 2015 07:22 PM.

Discussions are closed to public comments.
If you need help with Cascade CMS please start a new discussion.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac

 

26 Aug, 2016 01:19 PM
25 Aug, 2016 03:02 PM
25 Aug, 2016 12:50 PM
24 Aug, 2016 08:43 PM
24 Aug, 2016 07:20 PM
21 Aug, 2016 01:20 PM