Printing out metadata values of asset listing into an array


(Ryan Archer) #1

Have a brainteaser...

 

I currently have News Items which have comments enabled so that the News Item can be rated. Following Greg Sherwood's example on his blog here http://gregsherwood.blogspot.com.au/2008/03/rating-content-and-calculating-average.html - I have created a system whereby the average rating is stored in the metadata that is applied to all of the news items.

 

Now I am creating an asset listing page where the news articles are listed and ordered by the most popular to the least popular. Easy enough to order by the metadata value and I've also used the HTML5 <progress> tag to make a nice little bar graphic.

 

Now I was thinking of taking this one step further and incorporating D3 JS logic within the page. Now to do that, I am looking for a way to 'print out' all of the metadata values into an array.

Right now, I am having difficulty trying to construct a way to do it. I have attempted to apply a paint layout to the asset listing but that's not working out either. Problem is that I am trying to list out the data on the page and at the same time 'list out' the metadata into the JS array and it's really a conflict of presentation.

 

I think the only way to get around it is to make a separate asset listing just to get the metadata value out just for inserting into the array, AND

another asset listing to present the data on the page...


(Ryan Archer) #2

Think i managed to solve this one but it was slightly complex (more than i wanted it to be).

I created another asset listing that just pushed out the metadata value for the average news item rating and put it within a JS array.

 

Then I nested this asset listing into the former and was able to get the proper array into the function and use D3js to visualise the data.

Did get slightly complex as I had to put arrays within arrays so I could get both the metadata value and the asset name into the graph visualisation as text. E.g.:

 

Default format:

[%asset_metadata_Average.Post.Rating%,"%asset_name%"],

Type formats > Default format:

var dataset = [
%asset_listing%
];

d3.select(".chart")
  .selectAll(“div”)
    .data(dataset)
  .enter().append(“div”)
    .style(“width”, function(d) { return d[0] * 5 + “px”; })
    .text(function(d) { return d[1] + d[0];});


(Peter McLeod) #3

Hi

 

Depending on the specific situation, we sometimes use the listing to just output the HTML content and then use javascript to create the array rather than creating another listing to do this.

 

Generally, to simplify things we add the data that would be needed as data- attributes in the items, but you could get it from anywhere in the HTML.

 

Eg in your content listing: 

<div class="news" data-news-rating="%asset_metadata_Average.Post.Rating%" data-news-name="%asset_name%" ...

Then build the array on load (could also do some validation/tidy up here if needed):

var dataset = [];
$('.news').each(function(){
  dataset.push([$(this).attr('data-news-rating'),$(this).attr('data-news-name')]);
});

Then use the data array in your d3 code..

 

Thanks

Peter


(Ryan Archer) #4

Unique way of doing it Peter, nice.

However, will this still work in IE8 as it uses some HTML5 data attribute?

 

Unfortunately we still have to (somewhat) support that terrible, terrible browser...


(Peter McLeod) #5

Hi

 

I think it should, but what you are doing is really a progressive enhancement anyway...

 

You could always just store the data in standard tags and access the inner html in the same way, and hide for modern browers.

<span class="news-rating">%asset_metadata_Average.Post.Rating%</span>

Also - you may run into some issues with D3 on ie8.

 

Thanks

Peter


(Ryan Archer) #6

Yeah moot point really i suppose...