Since the admin interface has evolved quite a bit since we posted the concept that we were planning to implement i thought I would post some screenshots of the admin interface…
We’ve recently commited some new features for both users and developers all to do with duplicating items.
It is now possible to duplicate:
- items (including nested lists) within a list
- items (including nested lists) to another list
- the contents of a list to another list
To prevent cluttering up items with another action icon, you first click the copy item link, then select the item you wish to copy from a second screen, finally if you are copying to another list you select the list you wish to copy to. Here are some screens of the process.
Developers can now get a duplicate of any object that extends List8D_Root by called the duplicate() method.
$list = new List8D_List();
$list = $list->getById(1);
$duplicate = $list->duplicate();
The duplicate is exact in every way except id. This means that when duplicating branches (items or nested lists) the order is exactly the same, since it is impossible for two items to exist in one place only one will appear (we may change this later). It is therefore necessary to change the position and/or the list the duplicate is on.
$item = new List8D_Item();
$item = $item->getById(1);
$duplicate = $item->duplicate();
This code will move the item to the end of the list it is on.
$item = new List8D_Item();
$item = $item->getById(1);
$duplicate = $item->duplicate();
Using the move to method will place the item immediately after the original, however this is much slower as we haven’t optimised the moveTo method yet, and requires the position of all items on that list to be adjusted.
I’ve just finished committing the front end application to the repository, its finished but hasn’t been user tested yet so am still expecting a certain about of revision over the coming months. The first stage of user testing will be with academics when they are given the system on the 7th June, who have expressed a strong desire to see lists as users will. After they are happy with the display of lists we will try and squeeze in some student testing before the launch proper.
The logo and institution and application names can be controlled in the theme.ini config file and of course you can just extend the theme and create your own variation on it using the theme engine we’ve created.
Due to a bug in the metatron handler (thing that grabs resource information) when these items were added there is no cover art, however we have now fixed it, and covers are now retrieved from Google Books.
Problem: how do you select all the descendants all the way down a branch in a hierarchical MySQL table? Ie a table with the structure id, parent_id, etc where parent_id refers to the same table. This problem seems to crop up a lot with MySQL since there is no elegant solution provided natively, in fact it cropped up in the list8D development when I want to select tags in a certain namespace and the number of lists on them, the number of lists including the lists that had been tagged with tags that are children of the tags at the specified namespace. There are a few solutions but what I’ve found to be the best is poorly and rarely covered so I though I would write it up here.
The other options
The nested set model
The most common solution to this problem is the nested set model, I wont go into the details of how it works, but will just say that it means changing your table, it makes it complicate to write changes to the table, makes managing the table manually almost impossible, and it turns out is slower than my suggested method.
I saw a solution on stack overflow that meant creating duplicate rows with the parent_id for each ancestor not just the parent row, this would make getting the data I need out easy but creating and managing that table seemed very complicated and certainly wasn’t the solution I was looking for.
Do it in the application layer
This would mean looping over each tag getting its children and repeating, I didn’t try it but was willing to bet that would be way too slow.
The solution: create a loop in MySQL
There be procedures here
The solution I settled on I derived from a load of code I found here, it does mean programming a procedure and using a temporary table, but it is relatively elegant, doesn’t require any changes to the table (and therefore the code to write to it), and is in my experience so far very very quick.
Enough already show me the code
To start with we will get rid of the procedure we are going to create, your unlikely to have it unless you’ve already run the code, but chances are you will have to run it again and again until you get it just right.
DROP PROCEDURE IF EXISTS find_descendants;
The delimiter command changes the line delimiter from ; to go, this allows us to use the ; delimiter inside our procedure.
Now to start our procedure, a procedure is like a function except it can be called outside of a query.
CREATE PROCEDURE find_descendants()
In the same way we dropped our procedure before beginning, we will drop the temporary table we are going to create.
DROP TABLE IF EXISTS results;
Now to to create a temporary table to hold the all the children we are going to find.
CREATE TEMPORARY TABLE results
We will start by inserting the parent rows that we want to find the descendants of, in this example we are going to start with the tag with id 10. This query can return multiple rows if you wish to find the descendants of more than one row. Loading the id into a second parent_id column is important if you want to find the root parent of a row once we have iterated down the tree. You may not need this but I did as I was finding the descendants of multiple rows and needed to now which root parent they were a descendant of.
SELECT id, id as parent_id, tagname
WHERE id = 10;
I’m not sure if defining a primary key is entirely necessarily but its a good idea so here it is.
ALTER TABLE results ADD PRIMARY KEY(id,parent_id);
Now comes the magic bit, basically we are going to select the direct children of each of the rows already in the temporary results table we have created and insert them into the results table. And then repeat until there are no direct children of the rows in the results tables left to insert.
We need to to create a clone of the results table (results2) for the query due to the limitations of temporary tables.
DROP TABLE IF EXISTS results2;
CREATE TEMPORARY TABLE results2
SELECT * FROM results;
INSERT IGNORE INTO results
SELECT t.id, r.`parent_id`, r.tagname
FROM tag AS t
JOIN results2 AS r ON t.parent_id = r.id;
UNTIL Row_Count() = 0 END REPEAT;
Now to end our procedure, and reset our delimiter.
Finally will call the procedure.
We can now make queries on our temporary results table.
SELECT * FROM results;
Using this with PDO
I’m not saying that this isn’t possible with PDO however I’ve been unable to get it to work, I think, due to bugs in PHP’s PDO that prevent more than one query being performed within a query. I’m not 100% sure that there isn’t a way round it or simply something I’m doing wrong so would love to hear in the comments if someone has got this to work with PDO.
Very busy day today with 21 commits, including a bunch of bug fixes, the first 2 of 3 parts of a major new feature which I will explain another day as Simon is working on the 3rd and some new features at the code level:
- Forms now extend List8D_Form, which itself extends Zend_Form, the key difference being it will load decorators from the current themes /decorators folder, this needs some more work as the theme name isn’t in the decorators class name at the moment, which means its not unique.
- The findByData method has two new arguments, one to indicate you want to do a contains comparison rather than an equals comparison. And the second is a limit argument to limit the number of results you get back. I’ll probably move these arguments into an options array soon.
- Rather than having to check to see if a user can edit lists and then checking to see if they can edit that specific list it can now be done with one function call.
- Form errors are now styled nicely.
We’re currently running the final import so more of out time is going to be freed up to pursue new features. We’ve also got Matt Bull working a few days on the project here and there and Mark Fendly is going to be spending quite a bit of time on the project in the near future.
I haven’t been brilliant at making updates since my last resolution to make frequent updates, however there hasn’t been much to report on. Most of our time has split between bug fixing, and improving the import, bother relatively un-newsworthy .
Here are some changes that might be worth mentioning though:
Separating urls and meta urls
Before we had the ‘url’ field to hold a link to a resource, we now have ‘url’ which holds the link to an electronic version of a resource and ‘meta_url’ which holds the links to pages that hold information on that resource for example an amazon page or library catalogue page. There are no doubt going to be urls that fall into both categories but we will try and maintain the distinction where ever posible.
Permission to individual data fields
This feature isn’t quite finished, but it is now possible to define permissions to individuals data fields on resource’s.
Better end user error pages
Up until now error pages were designed for us to debug problems. Installations of list8D running in the ‘production’ environment will now display error pages designed for end users. Technical information like stack traces are still available, but are tucked away, this may change if emerges this information presents a security vulnerability.
With the shocking realisation that we had neglected the project blog for 4 months now I have resolved to blog on a frequent basis with a brief update of the changes that have been made to the development trunk.
I will only mention those changes which I think people (both other institutions and University of Kent users) will find interesting and will try and keep the technical jargon to a minimal. Please bare in mind that if you are an end user it may be a number of days/weeks before the changes are applied to the live server. With this in mind I will make a note of the revision (a revision is like a version number, each change gets a new number, the higher the number the later in development) that the change has been made in and I will also be posting an update when we make an update to our live server so you know what revision we are running. If the currently running revision number is lower than the revision of the change your will not yet be able to see the effects of that change.
Anyhow to business, today I’ve added a lot of new exciting stuff, most of it is very immature and basic, but should provide a good foundation and lots of options moving forward:
- Separating referencing from theming (r1067)
- This will give other institutions the option to create custom referencing systems based on their own needs with out having to interfere with the theming
- It also opens the possibility of having multiple referencing systems with the user choosing the one that suits them best
- Improvements to the front end view (r1070)
- Its still got a way to go but I added a bunch of improvements to the front end view including…
- Reference view for front end users
- With the ability to switch between that and a more standard content based view (r1074)
- The start of a reporting system (r1068)
- It is only a start but should provide the flexibility to meet all our (and other institutions) needs
- For now it just includes an all lists report and a for purchase report
It has been over four months since our last up date and I just wanted to let every one interested in the project know that we’re still here.
The lack of updates is in no way because of a lack of progress, quite the oposite in fact. We’re have had so much to do in so little time that our feet have hardly touched the ground. We’re currently preparing to launch list8D to academics and librarian staff on the 19th of April and are rushing to get as many essential features in before then as possible. The latest phase of development has been done in close consultation with librarian staff and academic representatives and we’ve fixed of whole host of critical issues they have raised and have tonne of requested features and tweaks for the next phase.
You only need to check our change log to see how much work has been going on recently. Here is an overview of the main features that we’ve implemented in the latest “release”.
- Support for nested lists
- Implemented a good looking UI
- Drag and drop reordering
- Core text recommendations
- LTI implementation for front end integration with Moodle and other VLEs
- A front end (at least the start of one)
Unfortunately we’ve been so busy preparing for a Kent launch that documentation has fallen by the way side somewhat, but we do hope to get things up to date when we get a spare second. We are also trying to pull together a beta release with step by step installation instructions, online demo and screencast but at this stage cant make any promises or provide dates so watch this space.
Title of Primary Project Output
List8D is an innovative user-focused Web 2.0 approach to creating and consuming university reading lists. External information sources are used to minimise data entry and provide direct links to library catalogues and other online sources.
Screenshots or diagram of prototype
The first screenshot is a photoshop mockup of the UI that we are working toward. The rest are as the prototype currently is now.
Description of Prototype
The prototype is still very much a work in progress, but we hope it is starting to show some of the ideas we want to build upon. We’ve aimed to build a very flexible system that can deal with many data sources and list/item types while continuing to be easy to use, and we feel we’ve succeeded at that.
It’s difficult to see this from the prototype, but we hope this will become more apparent as work progresses in future.
Link to working prototype
Example screenshots are shown above.
There is a demonstration “list8D in a box” Virtual Machine using the free VirtualBox available to download here. It is a large file (1.2GB) , and requires the virtualbox software, but it does give you a completely self-contained environment in which to play with list8D.
Link to end user documentation
Link to code repository or API
Link to technical documentation
Date prototype was launched
- Release 1 was tagged for release on 2nd of November 2009.
- Release 2 was tagged for release on the 30th of November 2009.
Project Team Names, Emails and Organisations
- Matt Bull <M.Bull@kent.ac.uk>
- Ben Charlton <B.C.Charlton@kent.ac.uk>
- Mark Fendley <M.S.Fendley@kent.ac.uk>
- Bonnie Ferguson <B.Ferguson@kent.ac.uk>
- Matthew Slowe <M.Slowe@kent.ac.uk>
- Matthew Spence <M.S.A.Spence@kent.ac.uk>
- Simon Yeldon <S.J.Yeldon@kent.ac.uk>
– All University of Kent staff.
Table of Content for Project Posts