PlaidWeb / Publ

Flexible publishing system for the web
http://publ.beesbuzz.biz/
MIT License
40 stars 4 forks source link

Better mechanism for content negotiation #157

Open fluffy-critter opened 5 years ago

fluffy-critter commented 5 years ago

Expected Behavior

It would be great to have a configurable and client-driven fallback mechanism for template resolution; for example, if there's both templates/feed.html and templates/feed.xml, have http://example.com/feed serve up feed.html to web browsers and feed.xml to RSS readers.

Current Behavior

Content negotiation is based on a hard-coded priority system that's universal to all templates, and disregards the client's request.

Context

Very useful for supporting more dynamism in templates and more user-friendly feed presentation and so on.

fluffy-critter commented 5 years ago

Thoughts: have some sort of configurable mapping (ideally on a per-category and/or per-template basis) that sets the content-type for each extension, and also a default q-value for use with the Accept: header (i.e. set a default priority internally but let the user-agent override it on a per-type basis) and then choose the highest q-value for which template to use.

This mapping file could also be where we can configure other headers for the response, such as cache-control or content-type, rather than continuing to use the crappy hard-coded mapping in rendering.py.

fluffy-critter commented 5 years ago

Specific use case: feed.html shows an h-card feed, feed.xml shows an Atom feed. In this case, we want to default to XML, unless Accept: ranks text/html higher.

fluffy-critter commented 5 years ago

Some further thoughts:

Rather than have these rules be set up in mapping files, it makes more sense to just make this part of static configuration for the app. This could be configured with something like:

app.configure_template('feed',
    priority=['xml','html','txt'],
    type={'xml':'application/atom+xml'})

which would configure the feed baseURL to have an extension mapping priority, and then specify that the xml form is specifically Atom (rather than the more generictext/xml). Both priority and type would be optional and would just fall back to the Publ defaults (and any unspecified content type would also fall back to the Publ default).

Then when a request comes in with an Accept header, we could parse the MIME types and map them back to an appropriate template based on the type mappings, and then use that to form a new priority list. (and always start the list with '' so URL-specified extensions always win)

fluffy-critter commented 4 years ago

If negotiation fails this should return an HTTP 406

I note this so that when I get around to making the custom template for beesbuzz.biz it'll be Lemongrab shouting UNACCEPTABLE!!!