Wrangling Custom Radius Tags

I’m integrating a beautiful Javascript app, InfiniteCarousel, into the Radiant extension architecture. The app creates a photo carousel:

A scrollable panel of images with nice left and right buttons, captioning, and links. If interested, feel free to install from github. The app is built largely in JQuery and has a pretty simple mark-up:

<ul id="headerCarousel">
<li><a href=""><img src="" /></a><p>the caption</p></li>
</ul>

To integrate as an extension, I first generated the extension, moved the JavaScript and CSS files to the public directory. Our version of the app used a link, as well, which was easy to integrate. We also wanted to avoid HTML and use a simpler Radiant tag. Radius is the tag markup language for Radiant, and developers and integrators can add to this library of tags. It will consist of one container tag, named “carousel” and a series of other tags that will be for each image in the carousel: “carousel.image.” The tags will render into the required mark-up, seen above as a UL set with LI for each image.

Radius tags are quite easy, in your Radiant extension “lib” directory, you create a file that defines the tags, and content to render when the radius standard tag class is executed. It’s pretty basic. But my output was like this:

<ul>
<li><img ... />
   <ul>
     <li><img ... />
       <ul>
         <li><img... />

I struggled with this for quite a while- reading up on Custom Tags- great resources, by the way, are:
- Adding Custom Radius Tags
- Adding a Custom Page Type. Doesn’t sound like it from the title, but near the end he does a very explicit and clear example of what was most challenging to me - extending a container and content tag, together.

My colleague Lorien figured it out first- the child tag was calling the parent tag each time it was rendered, so that’s why it was nesting within itself. To solve this, we re-named the child tag “carousel_image.” from “carousel.image.”

Final custom tag code:

module CarouselTag
  include Radiant::Taggable
  desc "Contains the panels of the carousel, and other objects."
  tag 'carousel' do |tag|
    content = '<div id="headerCarousel"><ul>'
    content << tag.expand
    content << '</ul></div>'
  end
  desc "Prints out the individual panels of the carousel."
  tag 'carousel_image' do |tag|
    %{ <li><a href="#{tag.attr['link']}">
      <img src=" #{tag.attr['src']}"></a>
      <p>#{tag.attr['caption']}</p>
    }
  end
end

Just to be clear about this- the child tag, “carousel_image” does not have a tag.expand command, which outputs the contents or guts of the tag. The parent, “carousel” does have the expand. By putting the child inside the parent in the HTML mark-up, the outer tag, with the “expand” command, will output all of the iterations of the children tags within it. This wasn’t that clear to me until the end of this project.

Radius/HTML:

<r:carousel>
<r:carousel_image src="/assets/13/medium/IMG_2631.JPG" link="http://www.banane.com" caption="Starting off on Broadway trail- nice and flat" />
<r:carousel_image src="/assets/14/medium/IMG_2634.JPG" link="http://www.banane.com" caption="First warming hut visit ever!"/>
<r:carousel_image src="/assets/15/medium/IMG_2637.JPG" link="http://www.banane.com" caption="Starting Junior Loop- which was crazy lack of signage"/>
<r:carousel_image src="/assets/16/medium/IMG_2639.JPG" link="http://www.banane.com" caption="Off roading on Sleeping Beauty trail"/>
</r:carousel>

How to include a block in a soap4r request

Here at Blazing Cloud we recently had to write some Ruby code to integrate with an external service via. SOAP. I cringed a little at the thought of working with SOAP, but I was pleased to find that the soap4r gem is fairly easy to use and works pretty well. Getting Started with SOAP4R is a nice tutorial that gave us most of the information we needed to get things working.

We did run into a gotcha that was tricky to solve. Our SOAP service required an authentication ticket to be sent with every request, and the format of this ticket required it to contain a <![CDATA[… ]]> block. We had to do a bit of finagling to convince the soap4r XML builder not to escape the < and > characters. Extensive searching on the interwebs told us that many others had run into the same problem, and nobody seemed to know how to solve it. But we were not to be discouraged! Nay, we persevered and found a simple solution that involves the use of a custom HeaderHandler. The use of HeaderHandlers in soap4r is well documented already in many articles so I won’t go into the details here. I will only discuss the steps required to send the <![CDATA[… ]]> block

Here is the general format required for our request header in our SOAP request (excluding the service details):

<soapenv:Header>
    <AuthTicket>
        < Value><![CDATA[blah blah blah here is the value]]></ Value>
    </AuthTicket>
</soapenv:Header>

And here is the code in our HeaderHandler that resulted in the desired header format:

class HeaderHandler < SOAP::Header::Handler
  def initialize(auth_ticket)
    @auth_ticket = auth_ticket
    super(XSD::QName.new)
  end
  def on_outbound
    raw_str = SOAP::SOAPRawString.new("<![CDATA[#{@auth_ticket}]]>")
    raw_str.elename = XSD::QName.new('http://www.someservice.com/ApiService', 'Value')
    auth_ticket = SOAP::SOAPElement.new(
          XSD::QName.new('http://www.someservice.com/ApiService', "AuthTicket"))
    auth_ticket.add(raw_str)
    SOAP::SOAPHeaderItem.new(
          auth_ticket, false, SOAP::EncodingStyle::LiteralHandler::Namespace)
  end
end

The two relevant lines of code for including the <![CDATA[… ]]> block are:

The SOAP::SOAPRawString type for the node that holds the value in this line of code:

raw_str = SOAP::SOAPRawString.new("<![CDATA[#{@auth_ticket}]]>")

The SOAP::EncodingStyle::LiteralHandler::Namespace encoding style on the header item in this line of code:

SOAP::SOAPHeaderItem.new(
    auth_ticket, false, SOAP::EncodingStyle::LiteralHandler::Namespace)

That’s it!

How to include a block in a soap4r request

Here at Blazing Cloud we recently had to write some Ruby code to integrate with an external service via. SOAP. I cringed a little at the thought of working with SOAP, but I was pleased to find that the soap4r gem is fairly easy to use and works pretty well. Getting Started with SOAP4R is a nice tutorial that gave us most of the information we needed to get things working.

We did run into a gotcha that was tricky to solve. Our SOAP service required an authentication ticket to be sent with every request, and the format of this ticket required it to contain a <![CDATA[… ]]> block. We had to do a bit of finagling to convince the soap4r XML builder not to escape the < and > characters. Extensive searching on the interwebs told us that many others had run into the same problem, and nobody seemed to know how to solve it. But we were not to be discouraged! Nay, we persevered and found a simple solution that involves the use of a custom HeaderHandler. The use of HeaderHandlers in soap4r is well documented already in many articles so I won’t go into the details here. I will only discuss the steps required to send the <![CDATA[… ]]> block

Here is the general format required for our request header in our SOAP request (excluding the service details):

<soapenv:Header>
    <AuthTicket>
        < Value><![CDATA[blah blah blah here is the value]]></ Value>
    </AuthTicket>
</soapenv:Header>

And here is the code in our HeaderHandler that resulted in the desired header format:

class HeaderHandler < SOAP::Header::Handler
  def initialize(auth_ticket)
    @auth_ticket = auth_ticket
    super(XSD::QName.new)
  end
  def on_outbound
    raw_str = SOAP::SOAPRawString.new("<![CDATA[#{@auth_ticket}]]>")
    raw_str.elename = XSD::QName.new('http://www.someservice.com/ApiService', 'Value')
    auth_ticket = SOAP::SOAPElement.new(
          XSD::QName.new('http://www.someservice.com/ApiService', "AuthTicket"))
    auth_ticket.add(raw_str)
    SOAP::SOAPHeaderItem.new(
          auth_ticket, false, SOAP::EncodingStyle::LiteralHandler::Namespace)
  end
end

The two relevant lines of code for including the <![CDATA[… ]]> block are:

The SOAP::SOAPRawString type for the node that holds the value in this line of code:

raw_str = SOAP::SOAPRawString.new("<![CDATA[#{@auth_ticket}]]>")

The SOAP::EncodingStyle::LiteralHandler::Namespace encoding style on the header item in this line of code:

SOAP::SOAPHeaderItem.new(
    auth_ticket, false, SOAP::EncodingStyle::LiteralHandler::Namespace)

That’s it!

Test Driven Development: Why it's awesome

I have been programming Ruby on Rails for about 3 months now, and have been following a fairly strict Test Driven Development (TDD) methodology using rspec for the duration of that time. Using TDD has been a great experience, and now that I’ve been doing it for a while I never want to go back to my pre-TDD ways. Here’s why:

I can describe my software in English before I write any code. An rspec test describes in English some particular behavior of a component such as “it returns the empty string if no record is found”. As you can imagine an entire suite of tests at this level of detail pretty well covers all of the behaviors of the component. Describing each behavior in English first frees my brain to focus only on implementation details when I’m writing the code.

I can focus on the details that matter and ignore the ones that don’t. When my brain is in coding mode it wants to account for every logical possibility and my code can easily become overly complex. Or I can overlook important edge conditions and end up with unexpected bugs. A good set of tests clearly defines the expected behavior and tells me when I’ve written just enough code to satisfy the requirements.

It is easier to read test descriptions than it is to read code. The test descriptions help me quickly identify the interesting code without having to follow method calls or conditional logic. The tests themselves are full of examples for how to use the component, so reading tests is an excellent way to quickly learn the details of a third-party API. Spelunking through code that has thorough test coverage can actually be a pleasant experience!

And of course there are fewer bugs. According to my project management tool, on my current project there are on average 3.7 bugs for every 11.7 features. With so few bugs I don’t have to go through a tedious as stressful bug fixing cycle at the end of the release!

In conclusion, TDD is awesome. It makes programming more efficient and enjoyable. If you are a software developer and you have not tried TDD I highly recommend you give it a chance.

Test Driven Development: Why it’s awesome

I have been programming Ruby on Rails for about 3 months now, and have been following a fairly strict Test Driven Development (TDD) methodology using rspec for the duration of that time. Using TDD has been a great experience, and now that I’ve been doing it for a while I never want to go back to my pre-TDD ways. Here’s why:

I can describe my software in English before I write any code. An rspec test describes in English some particular behavior of a component such as “it returns the empty string if no record is found”. As you can imagine an entire suite of tests at this level of detail pretty well covers all of the behaviors of the component. Describing each behavior in English first frees my brain to focus only on implementation details when I’m writing the code.

I can focus on the details that matter and ignore the ones that don’t. When my brain is in coding mode it wants to account for every logical possibility and my code can easily become overly complex. Or I can overlook important edge conditions and end up with unexpected bugs. A good set of tests clearly defines the expected behavior and tells me when I’ve written just enough code to satisfy the requirements.

It is easier to read test descriptions than it is to read code. The test descriptions help me quickly identify the interesting code without having to follow method calls or conditional logic. The tests themselves are full of examples for how to use the component, so reading tests is an excellent way to quickly learn the details of a third-party API. Spelunking through code that has thorough test coverage can actually be a pleasant experience!

And of course there are fewer bugs. According to my project management tool, on my current project there are on average 3.7 bugs for every 11.7 features. With so few bugs I don’t have to go through a tedious as stressful bug fixing cycle at the end of the release!

In conclusion, TDD is awesome. It makes programming more efficient and enjoyable. If you are a software developer and you have not tried TDD I highly recommend you give it a chance.

Drag Order Fix For New Blank Pages

We forked Drag Order extension, a cool extension for Radiant CMS, and fixed some stuff. What we didn’t take into account in our last fix was this case:

1) Create new pages, or import a data set with a ton of new pages
2) Try to reorder a page.

Turns out, the way it’s written, there’s an assumption that there’s just one new page:

# Set initial position if the page has none yet
    if @page.position == nil
      @last_page = Page.find_all_by_parent_id( @page.parent.id,
             :order => [ "position DESC" ], :limit = > 1 )
      @last_page.each do |p|
        @page.position = p.position.to_i + 1
      end
    end

So in our case we had multiple new pages-and the above would only work on one of them, the one being dragged. Later it would fail because there are other nil pages.

We ended up replacing the above block, to query for more records.


    all_new_pages = Page.find_all_by_parent_id( @page.parent.id,
                 :conditions => ["position is null"] )

Once we have that set, we query the rest of the records to find out the inherent order. To find out this order of pages as the user sees it- and expects it, you could argue- we just mimic the query that’s on the index view for Radiant’s admin pages page, :order=> "position ASC"

 if(all_new_pages.size > 0)
      all_pages = Page. find_all_by_parent_id( @page.parent.id,
                   :order => ["position ASC"] )
      i = 1
      all_pages.each do |p|
        p.position = i
        p.save
        i += 1
      end
    end

We do a basic enumeration to determine the position in the array, and assign it to the page.


p.position=i
p.save

This works fine, but at this point in the code, the original arguments passed in - there are 4, two of which are the used to create local arrays of database records, are now out of date. So we reload those from the database:


   @page = Page.find(params[:id])
   @rel = Page.find(params[:rel])

using pluralize in a radiant custom page

I’m working on extending the custom tags in the radiant-search-extension. Radiant tags are really a lot like Rails views, but they don’t have access to the view helpers. After learning how to call helpers outside of views, I simply added this method to my custom page:

  def pluralize(*args)
    ActionController::Base.helpers.pluralize *args
  end

PostGres & MySQL Fixes For Drag Order Extension (for Radiant CMS)

We were experiencing an odd behavior with the very popular Drag Order extension. This extension allows you to re-order your pages in the Admin screen, and for that new order to be reflected in any loop on the front end, also via the children tag.

The aberrant behavior appears when you add a new page. If you try to drag and drop the page, the function re-numbers the list with duplicates.
take 3 pages:
1
2
3

Add a new page, 2.5. If you move it by drag and dropping to between 2 and 3, it will end up here:

1
2.5
2
3

If you look in the database, the position column, added by drag_order, on the Pages table, will have 2 “2″ positions.

This doesn’t occur in SqlLite; it does occur in MySQL and PostGres.

We installed PostGres, uninstalled Drag_Order (which involves some manual database dropping) and isolated the issue. We were unable to output to logger. Still trying to figure out that one. But we were able to run each statement in console, which is where we discovered the problem: the new page has a nil position value. When sorted, by the position, descending, the 2 databases in question consider Nil as a higher value and will float it to the top. After some other functions add and subtract position values to re-order siblings in the list, this value becomes “2″. Thus, a duplicate 2 in the list.

We changed the SQL to include a condition for no nulls. “:conditions => ” position is not null “. After re-testing, the lists were ordered correctly.

The fork for this fix is at: Banane fork of Radiant Drag Order on GitHub.

PostGres & MySQL Fixes For Drag Order Extension (for Radiant CMS)

We were experiencing an odd behavior with the very popular Drag Order extension. This extension allows you to re-order your pages in the Admin screen, and for that new order to be reflected in any loop on the front end, also via the children tag.

The aberrant behavior appears when you add a new page. If you try to drag and drop the page, the function re-numbers the list with duplicates.
take 3 pages:
1
2
3

Add a new page, 2.5. If you move it by drag and dropping to between 2 and 3, it will end up here:

1
2.5
2
3

If you look in the database, the position column, added by drag_order, on the Pages table, will have 2 “2″ positions.

This doesn’t occur in SqlLite; it does occur in MySQL and PostGres.

We installed PostGres, uninstalled Drag_Order (which involves some manual database dropping) and isolated the issue. We were unable to output to logger. Still trying to figure out that one. But we were able to run each statement in console, which is where we discovered the problem: the new page has a nil position value. When sorted, by the position, descending, the 2 databases in question consider Nil as a higher value and will float it to the top. After some other functions add and subtract position values to re-order siblings in the list, this value becomes “2″. Thus, a duplicate 2 in the list.

We changed the SQL to include a condition for no nulls. “:conditions => ” position is not null “. After re-testing, the lists were ordered correctly.

The fork for this fix is at: Banane fork of Radiant Drag Order on GitHub.

Radiant CMS: Improving Drag & Order

In the Radiant administration interface, we wanted to allow our CMS users to be able to move pages around and have that final order in the navigation. Well, that is solved by an existing extension- the Drag and Order by Bright4.

We decided to change the icon to make it jump out more, and to turn off rollover highlighting when the user is dragging the page. This post is about changing the highlight rollover functionality.

The rollover highlight is set with CSS, in Radiant’s main.css Line 257:


#content table.index tr.highlight,
#content table.index tr:hover {
  background-color: #ffffb3;
}

So we needed to essentially turn the tr.highlight/tr.hover off when an object is being dragged, then turn it back on again after dragging, so the rest of the application still has this rollover functionality.

At first, we wrote our own JavaScript file and included it in the header partial, and on the events of MouseUp and MouseDown for the drag image.

A week later, I reviewed the Drag Order JavaScript, and was able to consolidate our changes within that script. When assessing all of the TRs for the table, I inserted a quick loop through all TRs and setting the background color to white:


	// scroll through all trs and set bgcolor to white to reset hover
	 var myTrArray = this.origRow.parentNode.getElementsBySelector('tr');
	 myTrArray.each(function(i) {
		    if(i.id != ''){ $(i.id).setStyle({ backgroundColor: '#ffffff'});}
	 });

This is on line 77- in the DragOrder function.

It’s great to consolidate a lot of changes in 4 lines!