RFC: Subject Browse Plugin

94 views
Skip to first unread message

pobocks

unread,
Mar 23, 2011, 5:51:34 PM3/23/11
to Omeka Dev
So, I've developed a very simplistic Subject Browsing plugin for
Omeka, as part of contract work for the Haystack digital library.
They've given me permission to release it to the community, and I'd
like to do so - but I'm not quite confident enough in it to do so
yet. I'd very much like comments, criticism, and a general thought on
whether or not I'm doing things reasonably.

The plugin (thus far) functions as follows: It creates a new view
(and route to that view) off of "items," and enters an additional item
into the sub-navigation for the browse pages (if they're set up using
a named nav helper). This page pulls a list of all the DC subjects
present in the database, and builds links to an advanced search on
those subjects for each subject. It also outputs headers for #0-9
(which is inclusive of subjects starting with symbols) and for each
letter of the alphabet that is represented.

There's some other formatting/navigation stuff, but it's all pretty
simple HTML, and easily grasped from the code, which is available
here: https://github.com/pobocks/SubjectBrowse

Again, any comments, criticism, suggestions, etc, are more than
welcome. This is my first Zend project, and I found the documentation
a little hard to adapt to Omeka's implementation of it. I would
particularly LOVE a close analysis of how the route is set up - I'm
still convinced I did something wrong-but-functional there, because
going to '/subject-browse' shouldn't work, AFAICT, but it does.
Ideally, only '/items/subject-browse' should work. I also am not 100%
sure I understand how Zend controllers work.

- Dave Mayo

John Flatness

unread,
Mar 24, 2011, 12:32:04 PM3/24/11
to omek...@googlegroups.com
I haven't yet actually test-driven this code, but it looks pretty good. You've basically nailed the view/controller structure of an Omeka plugin.

A few things I noticed just at first glance:

- It looks like you don't need your ItemsController. Your custom route is redirecting to your IndexController, and that's the one you wrote your view script for also.

- You have some written-out SQL for determining the ID of the Dublin Core Subject element, and this is included in your plugin.php file. This means that query is going to run on every page load in Omeka for users who have this plugin installed. If you do want to do a separate query for this, I would consider moving it to your IndexController's indexAction.

- On sort of the same subject, Omeka generally tries to conform to the MVC pattern throughout, so we'd generally discourage running an SQL query in your view script. You could page through the subjects and build out an array of the links you want to display, and have your view script act only on that array.

As for your question about your custom route, it looks like you've pretty much got it right. The define_routes code you have correctly adds a new custom route at items/subject-browse which points to your plugin. The reason you're still able to go to /subject-browse is because Zend's (and Omeka's) default route includes a route that matches against your module. So, /subject-browse matches your IndexController's indexAction, and adding your new route doesn't remove the default one.

-John

> --
> You received this message because you are subscribed to the Google Groups "Omeka Dev" group.
> To post to this group, send email to omek...@googlegroups.com.
> To unsubscribe from this group, send email to omeka-dev+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/omeka-dev?hl=en.
>

pobocks

unread,
Mar 24, 2011, 2:11:19 PM3/24/11
to Omeka Dev
Thank you very much, John.

The ItemsController is, in fact, an artifact of exploratory
programming - basically when I was trying to bang on Zend until I
understood it.

So, is there a place to put that query where it will run once on
install, define a constant forever, and then undefine that constant on
uninstall? Once it has that ID, it won't change over the course of an
installation of Omeka, unless something has gone seriously, seriously
wrong. I'm not entirely sure how calling define with a dynamic source
for the data works.

I figured running it in the view script was wrong, but I wasn't
entirely sure where to do it. I didn't think the plugin was actually
complex enough to need an explicit model - where would the proper
place to run that query be?

The routes and controller interfaces are where I feel the least
comfortable, and it's nice to know I'm not off base there.

Again, thanks very much for taking the time to look at this.

- Dave

John Flatness

unread,
Mar 24, 2011, 2:34:55 PM3/24/11
to omek...@googlegroups.com
It's no problem looking over code people are writing for Omeka. Omeka lends itself fairly well to being customized quite a bit from site to site, and we'd really like to encourage people to post these kinds of customizations, even ones that aren't yet factored out into a reusable form like your plugin is.

PHP's define is only going to make a definition persistent for one request (though this may be different with some PHP caching systems like APC).

Personally, I think your best bet at the moment would be to include both queries in your controller action code. This gives you the benefit of not running that subject id query on requests that don't need it, and moves your other query out of your view. If you really want to run that check about the subject id only once, you could run the query in your install hook and set an option in the Omeka DB with set_option. Afterwards, you could use get_option to get that id to create your query.

I don't think you do need a model class for this. There's a school of thought that would be more militant about keeping SQL out of the controller code, but I don't necessarily subscribe to that. For better or worse, models generally arise in Omeka plugins when the plugin is creating its own tables in the database.

On the topic of your "real" query, the one that's in your view right now, I've taken a closer look at it, and it looks to me like it's a little over-complex. You're only retrieving the 'text' column from the ElementTexts table, but you're also joining against the ElementSets and Elements tables. That initial query you're doing to determine the Subject element ID allows you to skip those extra joins entirely. When you're not dealing with Item Types, a particular element ID uniquely describes a particular element of a particular set. All you should need to do is select from the ElementTexts table where element_id = (the id you determined earlier).

Have you considered making an admin view for this as well? This could also be a convenient way for admins to look through their items.

-John

pobocks

unread,
Mar 24, 2011, 4:56:45 PM3/24/11
to Omeka Dev
I'm a little stuck on how to make a variable created in the
indexAction accessible from the view. If I can do that, though, I
think both your points here are extremely helpful - that's where those
queries SHOULD live, and reducing that query's complexity will be a
big readability win (although due to mySQL caching, I don't think it's
a huge performance concern.

It seems to me that using the set/get option mechanic is probably not
a performance win, at least not if that option is coming from the
database. I don't know where option values live when they're home, so
to speak - in any case, that's more optimization than I should
probably be doing at this stage of development.

The admin view idea is nice, and I'll definitely want to do that
someday - what I really want to do, as soon as I've delivered this
version, working, to the client, is to abstract out a bit, so that
this can be used to create a browse for any of the various Elements.
Barring that, it would at least be nice to be able to browse by the
Type element as well.

- Dave

John Flatness

unread,
Mar 24, 2011, 5:17:04 PM3/24/11
to omek...@googlegroups.com
On Mar 24, 2011, at 4:56 PM, pobocks wrote:

> I'm a little stuck on how to make a variable created in the
> indexAction accessible from the view.

From the action method, you should be able to do:

$this->view->variableName = $whatever;

Then you will have access to $variableName in your view script.

> It seems to me that using the set/get option mechanic is probably not
> a performance win, at least not if that option is coming from the
> database. I don't know where option values live when they're home, so
> to speak - in any case, that's more optimization than I should
> probably be doing at this stage of development.

Normally you'd be right on this fact, but since Omeka uses so many options on every request, it already reads the whole options table into an array.

So, getting an option is really just an array access, it doesn't incur an extra query.

-John

Reply all
Reply to author
Forward
0 new messages