August 8, 2007

I am currently working on the “Nested Sortable Widget” that I mentioned in the last post. I wanted to be able to showcase it in this post already, but I realized I was taking too long to give out some feedback, so I decided to write just to give some news.

The widget is almost complete, but I am running some issues with pagination, which is a lot more complex than I initially thought, primarily because you can’t show exactly the same number of items per page, due to the nesting (the pagination needs to be “soft”). But I think I am on my way and should be complete in the next 2 or 3 days. Summing up it will be able to fetch a list of nested elements represented in JSON, will display it, allow the user to change the order/nesting and will send it back to the server.

In the meanwhile I created a Google Code project for the NestedSortable plugin and hosted it there.

I hope to be able to write again pretty soon, with good news!


Nested Sortable jQuery Plugin

July 22, 2007

UPDATE: The plugin has now reached its 1.0 version, and is available in a compressed version and with documentation. Please check the project homepage at: http://nestedsortables.googlecode.com/

I am showing now the first version of what I call the “Nested Sortable” jQuery plugin. It is based on the same nesting idea shown on the previous prototypes and used on the bbPress forum ordering, but it is totally rewritten and has a very different (and I believe simpler/more efficient) inner working.

A demo of it can be seen here.

The highlights of it are:

  • Built on top of Interface ‘s Sortable and maintains compatibility with it. This means you can use the same options available on the Sortable, plus a few extra ones specific to the nesting. You can also mix Sortables and NestedSortables on the same page.
  • Just as easy to use (see the code examples on the demo).
  • Can be easily configured for left-to-right or right-to-left nesting.
  • Can be used with any type of HTML element (that allows nesting), not only ULs and LIs.
  • You can define a class for the nesting the draggable is currently hovering on, to make it clearer to the user (see my ugly yellow example – could be made pretty with some css styling).
  • All the previous bugs/misbehaviours with the prototype are gone (hopefully without additional ones being introduced).

It was tested under IE7 and FF2. What is still lacking for it to be complete (and useable) is a serialization function, which I should finish in a few days (serialization is now complete, see my comment bellow). As things evolve I should probably add a few callbacks to allow its behavior to be easily configured.

So, the next step for the WordPress page list project is to create a higher level jQuery plugin that will be built on top of this one and will, given a JSON object input, fetched via AJAX, dynamically create the Nested Sortable, with pagination support, using the idea Mike gave on the last comment (the user hovers over a Droppable, which should fetch and display the additional pages). It will be more like a widget.


More advances

July 10, 2007

First things first: I made some updates in the prototype. It now works as expected, allowing you to make a page a child of another page which doesn’t have children yet.

I also show in it what I think is the best way of handling pagination. The idea is to display an item from the main hierarchy before and another one after the items that belongs to the current page, in the ordering view. If the before/after main hierarchy item has children, all of its children should be displayed as well. In the demo, my before and after main hierarchy items are child less, therefore the “items bellow this” and “items above this” markers show up after one item, but that would vary. I did a lot thinking into this and think this is the only (and simpler) way you can move main items from one page into the other, without having “dark spots” (elements that are “stuck” in a page).

In trying to understand what was making nesting not working in the prototype, I had to dissect the Interface plugin code for the Draggables, Dropables and Sortables. I found the code pretty cluttered and hard to understand, filled up with variables with names such as “oC”, “oD”, “a”. In fact, almost no variables have meaningful, unabridged names. I had to do a lot of debugging, using Firebug. The code is very coupled as well as, for instance, you have calls to the Sortables plugin being made from the Draggable and Dropable (you would expect the Draggables and Dropables, as lower level elements, to be unaware of the Sortables existance). I didn’t like the code, but at least I understand it now.

Meanwhile, I found out the the jQuery team (John Resig, the creator, included) are creating an official, brand new set of UI plugins for jQuery. It is called jQuery UI. I wonder why they decided to skip Interface all together. It was not released yet, but already have working Draggables, Dropables and Sortables. I checked it out from SVN, looked at its code and tested it. The code is a great step foward from what I saw in Interface. Much cleaner, commented, well organized and easy to understand. Impressively, it also looks like they managed to keep it a lot smaller (30kB against 46kB of Interface’s). The coupling problem I mentioned doesn’t exist, as they created a generic callback in the Dragabble (called dropBehaviour), that the Sortable implements. That way, I could, for instance, create a brand new Sortable-like plugin, without having to modify Draggable’s or Dropable’s code. They seem to be tackling the “Sortable with Hierachy” problem as well, and have some partially working demos for it, in their test files.

Regarding the server side implementation, I am leaning towards passing the javascript a JSON representation of the page list, instead of generating the whole UL list in the server side. I think it will make things much more reusable, in both ways (reusing the javacript and the server side script). It will also download a lot faster for the client. I was thinking of using a JSON like this:

"columns":["Title(ID)", "Owner", "Updated"],
"info":["My Title(1)", "My Owner", "My Date"],
"info":["My Title(2)", "My Owner", "My Date"],
"info":["My Title(3)", "My Owner", "My Date"],

In this example we have a parent page which has two children.  It doesn’t look so good because I can’t indent the code to display it here. I already implemented it on the prototype, so now, instead of loading the page list from an file with HTML and just displaying it, it loads a file with JSON and processes it to create the HTML on the fly. The JSON file for the prototype can be seen here: list_demo_json.js  The JSON file has 2kB, versus 6kB for the HTML with the exact same data.


Demo of the AJAX table swap

June 29, 2007

As promised, I am posting a static demo of the legacy page list being replaced, via AJAX, by its sortable version.  It can be seen here. With this approach, we won’t have to mess too much with the WordPress core and will have a very similar functionality to the one proposed before.

Summarizing,  we will have an AJAX call fetch the sortable version of the list (made with ULs and DIVs) when the user presses “Edit Page Order”. Alternatively, we could send this list already in the initial page fetch, and keep it stored in a variable, until the user pressed the button. We now need a “Cancel” button, because the user may want to return to the default view of the list without committing the page ordering changes. In the previous version we didn’t need the “Cancel” button, because everything that could be done with the page list could also be done when “drag” was enabled.

The look of the whole thing is still very rough. I think the sortable version shouldn’t have the “actions” column, and probably won’t need the “drag handle”, making the whole item draggable. They were essential in the previous version, but for this one, as the only function the sortable list will have is sorting, those things are pointless.

The sortable page list should probably have a more distinct appearance, making it easier to tell from the default page list. Also, the “standard” AJAX animations, informing the user something is being loaded, should also be included.

Another approach I have been thinking of, way more radical, would be generating the sortable version of the list from the legacy one, in realtime, using javascript, by interpreting the legacy list. It wouldn’t be very hard, as jQuery makes it very easy to search for things in HTML. The advantage would be not needing to mess with the page list php code at all and not having to load anything via AJAX (it would be faster for the user). But I think it would couple the code too much, and future changes in the table could break it. Even if that wasn’t the case, it feels too quick and dirty to me.

There are still some bugs in the sortable list (adding a page as a child of another who has no children yet is not working). Also, other ugly things are not treated (eg. the user could click twice in the Edit, before the list is loaded). But this is still a prototype. 😉

In the next two weeks, before “Mid-Term”, I should dedicate 24 hours a day to the project (with some occasional time for the bathroom and some junk food), so expect things to go much faster from now on. Unfortunately, here in Brazil it is winter and our vacations and shorter. Mine are only starting now and my college is very demanding, specially in the last weeks of the semester.


A dreadful week

June 23, 2007

This week is my last week for the college semester and I am really overwhelmed with the amount of reports and tests I have to deliver and study for. So I will leave a more detailed progress report to be posted next week. From next week on I will finally be on vacations, and I am planning to dive deep into the project.

For now, what I can say is that the path of dynamically reloading the page list, with AJAX, when the user presses “Edit Page Order”, as pointed out in the comments in my last post, seems to be the best. I plan on posting a working demo of that next week, as soon as college gets off my back for a while.


HTML Draft of the new WordPress page list

June 16, 2007

I managed to put together a HTML/CSS draft of what the new page list should look like. It can be viewed in this link. Please note it’s only static HTML, and the “Save Page Order” still doesn’t do anything.

The list, that looks like it was done with a HTML table, was implemented using only DIVs and ULs. This effect was quite hard to achieve, because CSS positioning was actually not designed to do that kind of stuff. A lot of tweaking had to be done. Some extra tweaking also had to be done to make it work in both Firefox and IE7 (didn’t test in other browsers).

As discussed in my previous post, using HTML tables (like the page list is currently implemented in WordPress) would make it very hard to implement the AJAX sorting behavior. Nesting of table rows is not supported by HTML (ok, I could nest whole tables, but the resulting HTML would probably look nasty, and I am still not quite sure it would be usable with jQuery’s Sortable class – I will probably try it latter on).

This UL/DIV approach does have some shortcomes. First, the columns don’t adapt to their contents like in regular HTML tables (when there is big chunk of text). If you enter more text than would fit in its original size, some text will overlap. This could be a problem with extra long user names and page titles (a solution would be to truncate the text, with JavaScript probably). Second, notice that I removed the “ID” column, present in the original WordPress page list. I wanted an “auto-stretch column” for the page title, but I could have only one, and it needed to be in the left side (if you see how the HTML you will understand why). Also, since the left side column size will vary to show nesting, the ID column, being very small, would fall out of place and look weird. I intend to write the ID at the end of the page title (something like “Page Title (ID:12)“). It could also be in one of the fixed columns in the right.

If you use Firefox and try to change the text size (View>Text Size), you will notice the list will resize gracefully and nothing will fall out of place. This is thanks to the fact I used “em” as the measure unit in the CSS positioning code.

The javascript (jQuery) that implements “drag and drop sorting” was ripped from bbPress, with minor modifications. A lot still needs to be improved/adapted/implemented on it, but already serves as a “proof of concept”.

I believe the end result resembles the original Page list quite satisfactory. This approach allows us to add/remove as many fixed width columns as required, making it usable also for other parts of WordPress that require sorting. The HTML code is quite clean (although the CSS is pretty complex and not so easy to maintain).


Ordering in bbPress

June 9, 2007

Begining with a small amend: I forgot to mention in my first post that in all GSoC projects we have mentors. A mentor is an expert from the the open source organization the project is being held for, that should guide and lecture us. My Mentor is Michael Adams (his blog and his bio), from Automattic (the company that created and supports WordPress). So, Michael, greetings from your padawan. : )

Now with the main topic:

I have been looking at bbPress, which is a forum software created by the WordPress folks. It has a “forum order” mechanism which allows reordering and hierarchization at the same time. It is pretty cool and functional. It also doesn’t get in the way of the user (who is not at risk of dragging things unwillingly). It uses jQuery and Interface’s Sortable element, aparently with a little hacking, but not much.

Read the rest of this entry »