Skip to main content

Once again ONCE

Back in September of 2007 I wrote a post here about using the ONCE RTML operator to speed up the yahoo store editor. In that article I mentioned that the ONCE operator has two modes, one to evaluate the operator's body once per publish and the other, once per page. What I said there was that while ONCE :publish has great potentials and practical uses, ONCE :page wasn't too useful. Well, today I must correct that statement, as I recently discovered two ways to use ONCE :page.

To recap, a statement like this:
TEXT ONCE :page
GRAB
CALL :some-template
will evaluate the body of the ONCE operator once on the page and output its result. So in the example above, it would only call the template called some-template once on each page and output whatever some-template writes to the page. So far so good, if you have this block only once on the page, then having ONCE :page in it makes no difference.

Now consider this: some Yahoo! Stores have a breadcrumbs trail both at the top and at the bottom of the page. In case of long pages, this can help visitors navigate the site. In that case, you would have to call the breadcrumbs template twice on each page.

To digress here a little, the breadcrumbs template typically walks through the pages leading up from the current page to the home page (index), and puts up a hyperlink for each page along the path, something like this:

Home > Countertop Appliances > Beverage Appliances > Electric Tea Kettles

Ok, what's the problem with this? Maybe I'll write another post about this, but the main problem with breadcrumbs is that when writing breadcrumbs code, you have to use either the WITH-OBJECT or the FOR-EACH-OBJECT operator to switch the context to each of the pieces in the breadcrumbs trail, so that you can grab the name of each of those pages (in the above example, Home, Countertop Appliances, Beverage Appliances). Using the WITH-OBJECT or FOR-EACH-OBJECT operator is "exensive", meaning it slows down your editor and your publish process, because the editor has to "fetch" those pages from storage (disk). So, if you have two breadcrumbs trails, you will do this twice per page. That's where ONCE :page comes in!


TEXT ONCE :page
GRAB
CALL :breadcrumbs.

....

TEXT ONCE :page
GRAB
CALL :breadcrumbs.

Take a look at the above code segment. Here, you have the top breadcrumbs, the page body (where the .... part is), and then the bottom breadcrumbs trail. However, in this case, the actual breadcrumbs code is evaluated exactly once, not twice. You essentially get the second one for free!



My second idea came from a small project I was working on recently. In a Yahoo Store, we had pages that had 3 types of "components" you could order: a kit, the individual kit components, and the tools used to put a kit together. We had three "references"-type fields for these called (you guessed it) kit, kit-components, and tools-used, so data entry personnel could put product IDs in all three of these fields. The twist was, they wanted to label each of the "sections". Below is a sketch of this setup.


In RTML, you could write three separate loops to achieve this:

TEXT "KIt"
FOR-EACH-OBJECT @kit
<... generate one line of the table ...>
TEXT "Kit Components"
FOR-EACH-OBJECT @kit-components
<... generate one line of the table ...>
TEXT "Tools Used"
FOR-EACH-OBJECT @tools-used
<... generate one line of the table ...>


In our case, the table was a little complicated, so splitting the code up into three segments was going to be a problem, but luckily, I was able to solve this using ONCE :page.

Instead of having three loops, I combined the 3 fields into one list using the APPEND operator, so I could have just one loop, but then, I used ONCE :page to put up the headers:


WITH variable kit
value @kit
WITH variable kit-components
value @kit-components
WITH variable tools-used
value @tools-used
WITH variable list
value APPEND
@kit
@kit-components
@tools-used
FOR-EACH-OBJECT list
WHEN POSITION element id
sequence kit
ONCE :page
TEXT "Kit"
WHEN POSITION element id
sequence kit-components
ONCE :page
TEXT "Kit Components"
WHEN POSITION element id
sequence tools-used
ONCE :page
TEXT "Tools Used"
<... generate one line of the table ...>


This is somewhat simplified of course, the headings had to go into their own table rows with table cells spanning the entire table width, but that's not the point here.

The point is, that using ONCE :page for the headers, I didn't need to care about where to output the headers, it just worked! Even if I had 20 items in, say kit-components, the "Kit Components" heading would only appear once thanks to the fact that it was output within a ONCE :page construct.

One final point: why did I save the values of the "kit", "kit-components", and "tools-used" properties into local variables? Well, this is a common mistake I see from RTML programmers: they forget that once they are inside a FOR-EACH-OBJECT or WITH-OBJECT expression, they are referencing the local properties of another page. By saving these properties in local variables, I can be sure that I can reference those instead of accidentally grabbing the values from each of the component pages.

Comments

Popular posts from this blog

Adding custom Yahoo Store fields - Catalog Manager vs. Store Editor

In a non-legacy Yahoo Store, there are two ways to add custom fields: through Catalog Manager under "Manage my Tables" and through the Store Editor, under "Types" (the Store Editor's "Types" are essentially the same as Catalog Manager's "Tables".) Whether you add custom fields from Catalog Manager or from the Store Editor does make a difference as each has its advantages as well as disadvantages. Catalog Manager To me the main advantages of using Catalog Manager to add custom fields are: 1) You can add multiple fields quicker 2) You can later change the field's name and even type 3) You can delete the field if you no longer need it. 4) All the fields that are available in Catalog Manager are included in the data.csv file if you download your catalog. 5) All the fields that are available in Catalog Manager are also included in the catalog.xml datafeed file, which is used by the comparison shopping engines, for example. (See the Search ...

Multi-Add and Yahoo Floating Cart Blues

Although the Yahoo! Floating Cart is considered pretty much bug free by Yahoo (you can look at the official open issues list here http://help.yahoo.com/l/us/yahoo/smallbusiness/store/floatingcart/floatingcart-09.html ) , there are some pretty "interesting" issues still, so since I keep running into them, I decided to post them here along with the work-arounds. The following issues all occur with multi-add forms only. 1) If you have your quantity set up as anything other than a simple text box (for example a drop-down SELECT box), the floating cart will not take the quantity value. It will take vwquantity as a customer-selected option. The workaround: use a text box instead. Nothing else works currently. 2) If you have a script that checks if the shopper made a selection from a drop-down (basically, any kind of an "onsubmit" handler), the floating cart will still receive the item, even if you cancel the submit event. The workaround: put the event handler on the click...

CPR for a Yahoo Store on Google's Supplemental Index

Recently a client of mine came to me and said that most of his store pages disappeared from Google, and he did not do anything to make this happen. I was a bit skeptical, so I went to Google, did a search on his store, and sure enough, there were only two pages indexed, his home page and his site map (ind.html) page. The rest were in the supplemental results, which means that Google thought the rest of the pages were not much different than these two pages. When I looked at the supplemental results, the little excerpts under each link were exactly the same, and I also noticed that what Google showed under each result was actually text from the ALT tags of the header image. I looked at some of these pages in my client's store, and they were actually different. This was a bit puzzling, but then I thought perhaps Google saw that the header and left navigation was the same throughout the site (which is pretty normal), but that the text that made each page different was too far down ins...