eevee/spline — Issue #34: Port to Pyramid
Author: encukou
Created: 2012-01-26 22:27:47+00:00
State: open
Labels: high-priority, involved, plugin core, refactor, target-version 2011 Q1

**Reported by [Eevee](http://github.com/eevee) on 2010/11/07 21:48:00 +0000 · Migrated from [Redmine issue 440](http://bugs.veekun.com/issues/440)**

---

Pylons is as good as dead. See: [http://docs.pylonshq.com](http://docs.pylonshq.com)/

It looks like its replacement, Pyramid, is a much better fit for spline’s plugin shenanigans anyway. Maybe this could be a good start towards making spline a real project.

Definitely don’t merge this until Pyramid has a non-alpha release.

Redmine metadata:
Updated on: 2011/11/15 08:32:50 +0000
Start date: 2010/11/07
Relations:
duplicated #608

---

**Comment by [Eevee](http://github.com/eevee) from 2011/04/22 04:43:24 +0000**

Might be nice to bail on setuptools at the same time. Not sure what Pyramid relies on, if it relies on anything.

---

**Comment by [Eevee](http://github.com/eevee) from 2011/04/28 21:27:50 +0000**

Things about Pylons that bother me that I would like to move away from in the process, if Pyramid isn’t bolted tightly to them:

- Setuptools.
- Nose.
- Paster in general, its absurd config file, etc.

Things about spline that are broken and this is a good chance to fix them since I’ll wreck everything in the process anyway:

- Where plugin resources live. We have JS, CSS, generic static files, templates, model code, and controllers. Each are namespaced independently. Makes for kind of a mess. Seems like plugins should act as self-contained as possible, but still be able to interact with each other if they ask nicely.
- How the “local” plugin works. At the moment it’s an isolated Python file, which is frightening.

category_id: None ⇨ 37

---

**Comment by [En-Cu-Kou](http://github.com/encukou) from 2011/11/14 00:58:44 +0000**

Setuptools: Pyramid is still using it. But, we should at least have plugins listed in the config file explicitly rather than just using whatever’s currently installed. And get rid of the namespace package thing for plugins.
On a related note, it would be cool to have two instances of a plugin, with different config (e.g. root URL), in one app.

Nose: Pyramid seems agnostic here, and [recommends unittest](http://docs.pylonsproject.org/projects/pyramid/1.2/narr/testing.html#unit-integration-and-functional-testing). Pytest seems very possible.

Paster/.ini: Pyramid uses that, though there are [plans to ditch it](https://github.com/Pylons/pyramid/wiki/Pyramid-2-brainstorm) in 2.0. For now we probably want to just live with it.
Pyramid doesn’t use \`paster make-config\` or \`paster setup-app\`. We’ll probably want to include sample development.ini files with the projects, and maybe auto-install on first run.

Plugin resources: Pyramid’s template mechanism wants mako.directories in the top-level config. Might want to (ugh) ditch that and call Mako directly. But maybe that’ll also help solve the mess with translators.
URL traversal should work wonders for controllers.

---

**Comment by [Eevee](http://github.com/eevee) from 2011/11/14 19:31:21 +0000**

I have a very simple attempt at this; it consists of a dead-simple core with a single template, and a plugin that adds a new URL with a different template.

Pyramid uses setuptools, but doesn’t strictly *require* it, and i believe there’s even a ticket somewhere for removing some light implicit dependencies on it. Or maybe i’m thinking of the paste stuff.

Plugins are already listed in the config file explicitly; loading everything is a bad default that should go away.

The namespace package would no longer be required, but i’ll probably keep using it anyway because it makes a lot of sense for plugins for the same thing to all live in the same hierarchy.

Two instances would be… possible, though tricky, and it’s not immediately clear what you’d use it for…

You don’t actually need to use \`mako.directories\`; Pyramid does some handwaving to make package resource paths work anywhere in Mako, i.e., \`splinext.pokedex:templates/pokemon.mako\`. It’s a bit more verbose, but paths are relatively uncommon and it avoids the crazy path overloading stuff so i don’t care about that. (Said overloading now becomes considerably more difficult if we ever *do* want it, but i’m not sure we do.)

Traversal will be interesting. I had a conceptual problem with it in floof that ultimately drove me back to routing: there’s no nice way to glue traversal to the ORM without heavily instrumenting the ORM, and that rings very backwards to me.

---

**Comment by [En-Cu-Kou](http://github.com/encukou) from 2011/11/14 20:23:00 +0000**

Eevee wrote:

> I have a very simple attempt at this; it consists of a dead-simple core with a single template, and a plugin that adds a new URL with a different template.

Share! I don’t want to duplicate your efforts.

> Two instances would be… possible, though tricky, and it’s not immediately clear what you’d use it for…

One example: The frontpage plugin basically implements its own plugin system now. It could just use regular plugins with a custom hook.

> You don’t actually need to use \`mako.directories\`; Pyramid does some handwaving to make package resource paths work anywhere in Mako, i.e., \`splinext.pokedex:templates/pokemon.mako\`. It’s a bit more verbose, but paths are relatively uncommon and it avoids the crazy path overloading stuff so i don’t care about that. (Said overloading now becomes considerably more difficult if we ever *do* want it, but i’m not sure we do.)

Sweet.

> Traversal will be interesting. I had a conceptual problem with it in floof that ultimately drove me back to routing: there’s no nice way to glue traversal to the ORM without heavily instrumenting the ORM, and that rings very backwards to me.

Yeah, the Pyramid docs want you to overload your model for this, which is of course messy if the model lives in an unrelated package. Don’t do that.
Instead, have a lightweight “controller” object for every node in the tree. I came up with something like this: [https://gist.github.com/1365007](https://gist.github.com/1365007)

Now all URL stuff should be done through these objects; to get a Resource for an ORM entity you‘d do something like dex\_root[’pokemon’].wrap (pokemon) in some helper.

My idea also pretty much does away with views, and has just Resources, with one universal view that calls render () or something. Saves the trouble of scanning or registering all the views in advance.

---

**Comment by [Eevee](http://github.com/eevee) from 2011/11/15 02:14:31 +0000**

En-Cu-Kou wrote:

> Share! I don’t want to duplicate your efforts.

Yeah, yeah… 8)

> One example: The frontpage plugin basically implements its own plugin system now. It could just use regular plugins with a custom hook.

Clever girl. Frontpage’s subplugins, though, are more logic than anything else.

Take the users plugin, which wants *both* a `/users` and `/account` namespace. How do we handle this just with Pyramid’s prefixing power?

> Yeah, the Pyramid docs want you to overload your model for this, which is of course messy if the model lives in an unrelated package. Don’t do that.

> Instead, have a lightweight “controller” object for every node in the tree. I came up with something like this: [https://gist.github.com/1365007](https://gist.github.com/1365007)

>

> Now all URL stuff should be done through these objects; to get a Resource for an ORM entity you‘d do something like dex\_root[’pokemon’].wrap (pokemon) in some helper.

And then you‘d generate a URL with \`request.resource\_url (dex\_root[’pokemon’].wrap (pokemon))\`?

Hmm. I can kind of dig that.

> My idea also pretty much does away with views, and has just Resources, with one universal view that calls render () or something. Saves the trouble of scanning or registering all the views in advance.

What’s the advantage of this over the existing Pyramid view mapping system? Sounds like you’d end up reinventing it.

Scanning is just `config.scan(splinext.pokedex.views)` — not particularly difficult.

---

**Comment by [En-Cu-Kou](http://github.com/encukou) from 2011/11/15 08:32:50 +0000**

Eevee wrote:

> Take the users plugin, which wants *both* a `/users` and `/account` namespace. How do we handle this just with Pyramid’s prefixing power?

By a plugin with two URL root classes. The root should be separate from the plugin itself anyway.
Anyway, users is the one plugin we just might want to have a singleton for, to ease interactions with other plugins. There could be plugins *for* users, though (openid, local, oauth, browserid, …)

> And then you‘d generate a URL with \`request.resource\_url (dex\_root[’pokemon’].wrap (pokemon))\`?

Actually `dex_root['pokemon'].wrap(pokemon).url` will do just that, as seen in that gist. The Resource instances are request-specific.

> \> My idea also pretty much does away with views, and has just Resources, with one universal view that calls render () or something. Saves the trouble of scanning or registering all the views in advance.

>

> What’s the advantage of this over the existing Pyramid view mapping system? Sounds like you’d end up reinventing it.

>

> Scanning is just `config.scan(splinext.pokedex.views)` — not particularly difficult.

One advantage is consistency: every URL has an object with the same interface behind it.
I guess I don’t really get what Pyramid’s view system is that great for.