What is the black magic occurring in this Wordpress theme?
January 10, 2012 5:34 PM   Subscribe

Can anyone help me make sense of the javascript/jQuery (and black magic?) behind the category list in the portfolio of this Wordpress theme?

I recently purchased this Wordpress theme. I have been happy so far, but I have been trying to make sense of the portfolio thumbnails view found HERE.

Now, I don't have a lot of experience coding or doing this sort of thing, so I have spent days doing my own sort of trial-and-error editing of these templates. The developer has actually been helpful, but I think I may be asking him a bit too much with this.

Basically, I can't really understand how the list of categories in the sidebar on the right is generated, and how I can edit it. The actual template uses a separate js file, much like I found in this example online. The demo site, however, seems closer to this.

In the demo, the list appears once the page loads in the area after the div named "filter_work" (in other words, that unordered list happens through the scripting).

The javascript that seems to be making this whole magic list appear seems to start after the variable "filterType" is declared.

In both instances, the list of categories on the right is created dynamically as the various portfolio items are generated, then the list just sorta pops up in the end. My problem is that it seems like the list of categories just pop in using the order they come up -- there is no way to set the order in advance, and it doesn't show the parent-child relationships of the categories.

I would love if I could have my list look something like:



I get that the current method is extensible, and will populate with new categories. I would love to keep it that way with the formatting above, but I would be willing to even hard code it in if I could have that kind of formatting instead.

However, given my limited grasp of how this whole thing is working, I can't even seem to find the place to sort the categories into the order I want. I have been fiddling with this for a while, but I just can't quite get where I should be doing this category manipulation since I don't really get the order of operations here.

I am working locally using MAMP on my machine, so I don't have a working site to show yet, but I was hoping the demo linked above would be enough.
posted by This_Will_Be_Good to Computers & Internet (11 answers total)
Is the list you're talking about:
Filter Works by:

If so, that's not populated or sorted by JavaScript, it's there when I turn off JS in Firefox.
posted by artlung at 5:51 PM on January 10, 2012

The JavaScript only appears to handle the actual filtering and indicating which of those items is selected, it doesn't actually generate the list. There will be some PHP in the WordPress template in the theme files that generates the list, which is what you'll want to look at to change the behavior. It might use get_the_category_list() for example (http://codex.wordpress.org/Function_Reference/get_the_category_list).
posted by jonathanweber at 5:56 PM on January 10, 2012

Response by poster: Once I purchased and set up the actual template, the code for the categories appeared to be built on the examples used here.

So, the javascript to generate the category list doesn't appear until the end, and it won't appear if javascript is turned off (I think in the demo, the list appears but it won't work).

Since the javascript is in a separate file, I wasn't sure if I could even use PHP like get_the_terms().

Also, on a side note: is this bad form to use a javascript-based list? Do a lot of people turn off javascript? The cool quicksand animation isn't as important to me as accessibility -- I am sort of learning all this on the fly, and just had hoped to have a clear category list.
posted by This_Will_Be_Good at 6:01 PM on January 10, 2012

Best answer: So in *that* demo, the "magic" is all in this JavaScript: http://demo.tutorialzine.com/2011/06/beautiful-portfolio-html5-jquery/assets/js/script.js.

The list is generated from this code:
<li data-tags="Print Design"><img src="assets/img/shots/1.jpg" alt="Illustration" /></li>
<li data-tags="Logo Design,Print Design"><img src="assets/img/shots/2.jpg" alt="Illustration" /></li>
<li data-tags="Web Design,Logo Design"><img src="assets/img/shots/3.jpg" alt="Illustration" /></li>
The list is gotten from those data-tags attributes and generated dynamically. I think by default no sorting or ordering occurs. I'm not sure what approach I'd take to do them hierarchically, but perhaps you can just remove the dynamic list generation and output that in PHP.

As to accessibility without JavaScript, I'm not sure lacking this wizzyness is a big deal, as long as the thumbnails are there and they link to more information about them. As to how much you need to account for no JS, that will depend on your audience.
posted by artlung at 6:11 PM on January 10, 2012

There are a lot of different ways to accomplish something like this -- what I've seen this called is "filterable" with jQuery.

See also http://www.wearepixel8.com/1201/create-filterable-portfolio-wordpress-jquery/ -- creating a filterable portfolio with wordpress and jquery.

I haven't ever used this solution, but just skimming it looks like it should work.
posted by kellygrape at 6:15 PM on January 10, 2012

Response by poster: artlung -- ok, so in that script.js file (that looks exactly like what I have in my template), everything has been sorted into that "itemsByTags" variable. However, that appears to be an "object" instead of an array. If I could sort the elements of that itemsByTags object, it would allow me to format my list. However, I don't understand two things:

1) how can you sort an object (as opposed to an array)?

2) can I call wordpress/PHP commands from within that separate script.js file, such as get_the_terms() so I can have a means of comparing or sorting categories, parents, etc?
posted by This_Will_Be_Good at 7:33 PM on January 10, 2012

Best answer: For 1, see http://stackoverflow.com/questions/1359761/sorting-a-json-object-in-javascript

For 2, no, in your JS files you cannot call any PHP functions. What you might do is create your list using get_the_terms() using likewise and dynamically generate your list on the server and in-page rather than after the fact, the way the first example worked.
posted by artlung at 6:31 AM on January 11, 2012

Response by poster: Ok, I am slowly making sense of all this...I didn't really get that the script was passing data secretly through tags in the DOM (I had never heard the term DOM). So, the list of categories was being backed up and passed back onto the page through a CSS class. That was some of the "magic" that eluded my limited knowledge. So, things that weren't showing up when I was looking at the source were there, they were just stored magically inside tags. This whole data method is really hard for me to grasp.

So, I was able to insert some javascript into that js file that proves I can sort a bit there -- I added this:

////******** SORT THE CATEGORES **********//
// var i;
// i=0;
// var testArray = new Array();
// for (x in itemsByTags)
// {
// testArray[i] = x;
// i++;
// }
// testArray.reverse();
// var sortedCats = {};
// for (x in testArray) {
// sortedCats[testArray[x]]=itemsByTags[testArray[x]];
// };
// itemsByTags = sortedCats;
////******** END OF SORTING **********//

That allowed me to reverse the list, which was just sort of a high-five to myself. However, without the ability to call PHP within the js file, I don't think I can do much more sorting beyond that without a lot of ugly code comparing lists. One other idea would be to do the sorting on the page, and then store that in some sort of variable or array that the js file could access to use when sorting out the lists.

I am going to try your suggestion and try to do the sorting and formation of the formatted category list on the page with PHP. I think i can figure that out, I am just having a hard time figuring out how to associate the data that is used in the Quicksand sorting feature with my sorted list.

[Oh, if I only had money to pay someone to do this instead of wasting so much of my time, but I am rapidly learning a lot of how this stuff works behind the scene so I guess all is not lost!]
posted by This_Will_Be_Good at 4:39 PM on January 11, 2012

So what's your actual data look like? How does it look initially as produced by PHP, and what do you need it to transform into?

One option is to output the data you need, sorted, in PHP, but set the style to display: none. Then if you add an id to it you can call it with jQuery.
posted by artlung at 5:26 PM on January 11, 2012

Response by poster: After following the advice here and a LOT of trial and error, I was able to get it to work. The tutorials on this page and the one here were both really helpful.

I was able to do the sorting with PHP in the page, and then just made sure to insert the classes the jQuery command would need. The way the data is flitted about through CSS tags is really confusing to me -- I like to be able to easily see where the data is, or call it up when I need to. I also installed FireBug in Firefox, so it was helpful to be able to insert breaks in the javascript and inspect variables.

Once I was able to get most of the pieces in place -- the javascript in my header, and the list in my page -- the biggest problem was just formatting. The list of data-types I was using originally was separated by commas. I guess that was the big problem as the find method wasn't able to search through the whole list that way. There were also some odd little differences between the two examples in referencing the CSS (sometimes there was a # sign, sometimes a period, at one point there was a tilde that I think meant contains somewhere).
posted by This_Will_Be_Good at 8:23 PM on January 12, 2012

Best answer: In jQuery:
$('#selector') would find an element <div id="selector">

$('.selector') would find an element <div class="selector">

$('li[data-type="Foo"]') would find an element like <li data-type="Foo">

$('li[data-type~="Foo"]') would find an element like <li data-type="Bar,Foo,Whatever">
find() would need the right jQuery selector put into it for it to work.

Glad you got it sorted out!
posted by artlung at 9:37 PM on January 12, 2012

« Older How do you become a Vulcan when reading email?   |   Have I ruined my boots with leather conditioner... Newer »
This thread is closed to new comments.