I'm working on converting an existing Drupal site to Pyramid. The Drupal site has urls that are SEO friendly example: "testsite.com/this-is-a-page-about-programming". In Drupal they have a system which maps that alias to a path like "testsite.com/node/33" without redirecting the user to that path. So the user sees "testsite.com/this-is-a-page-about-programming" but Drupal loads node/33 internally. Also if the user lands on "testsite.com/node/33" they would be redirected to "testsite.com/this-is-a-page-about-programming".
How can this be achieved in Pyramid without a major performance hit?
You don't really need all this stuff with Pyramid - it can handle nice urls natively.
Basically, your "page" model would have a slug
field which would store the SEO-friendly URL fragment:
class Page(Base):
id = sa.Column(sa.Integer, primary_key=True)
slug = sa.Column(sa.String, index=True, unique=True)
title = sa.Column(sa.String)
body = sa.Column(sa.String)
Then you would have a route which directly maps /:slug
url's to a view which would find a page by its slug and render it.
For backward compatibility purposes you may also have a view mapped to /node/:id
, which would simply redirect to the /:slug
view, but that's only needed if you want to preserve the old redirects.
Here's another variation of your Page model:
class Page(Base):
slug = sa.Column(sa.String, primary_key=True)
title = sa.Column(sa.String)
body = sa.Column(sa.String)
historical_node_id = sa.Column(sa.Integer, index=True, unique=True)
UPDATE: Regarding "Is there something like a server level redirect for wsgi servers that could be coded into a file rather than having to make a database query and then redirecting?" - this is the very definition of premature optimization :)
The cost of a browser making a request, receiving a redirect and making another request is often in the order of hundreds of milliseconds, especially if the server is on another continent - purely because of speed of light. Full page loading usually in the order of seconds. The cost of fetching a single row from a database running on the same machine is usually less than a millisecond - hundreds of times faster than the redirect itself.
But, if you insist, there definitely are ways to do that:
Hard-code the values in some dict:
HISTORICAL_URLS_MAPPING = {
'33': '/this-is-a-page-about-programming',
'34': '/this-is-a-page-about-premature-optimization'
}
def historical_node_id_view(node_id):
return HTTPFound(HISTORICAL_URLS_MAPPING[node_id])
Normally a Pyramid app is served behind an "industrial" web server, such as Nginx or Apache. You can drop a bunch of configuration lines into the webserver config.