惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog RSS Feed
K
Kaspersky official blog
Forbes - Security
Forbes - Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Proofpoint News Feed
G
GRAHAM CLULEY
V
Vulnerabilities – Threatpost
Security Latest
Security Latest
Scott Helme
Scott Helme
S
Securelist
美团技术团队
T
Threat Research - Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
S
SegmentFault 最新的问题
W
WeLiveSecurity
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Apple Machine Learning Research
Apple Machine Learning Research
The Cloudflare Blog
AI
AI
L
Lohrmann on Cybersecurity
S
Security Affairs
Cloudbric
Cloudbric
SecWiki News
SecWiki News
爱范儿
爱范儿
雷峰网
雷峰网
Engineering at Meta
Engineering at Meta
C
Cyber Attacks, Cyber Crime and Cyber Security
大猫的无限游戏
大猫的无限游戏
N
News and Events Feed by Topic
I
InfoQ
S
Secure Thoughts
AWS News Blog
AWS News Blog
A
About on SuperTechFans
Schneier on Security
Schneier on Security
酷 壳 – CoolShell
酷 壳 – CoolShell
The Last Watchdog
The Last Watchdog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
Check Point Blog
P
Palo Alto Networks Blog
博客园 - 【当耐特】
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Google DeepMind News
Google DeepMind News
Latest news
Latest news
I
Intezer
博客园_首页
C
CXSECURITY Database RSS Feed - CXSecurity.com
V
V2EX
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
L
LangChain Blog
D
Docker

Secret Weblog

Becoming More Xee: A Modern XPath and XSLT Engine in Rust Looking for new challenges! Repeat Yourself, A Bit The Curious Case of Quentell The Humble For Loop in Rust The Humble For Loop in JavaScript Don Question Best Practices I Was a 1980s Teenage Programmer Part 5: Achieving Assembly I Was a 1980s Teenage Programmer Part 4: The Call of Assembly The Tooling Shift I Was a 1980s Teenage Programmer Part 3: MSX-2 JavaScript: when you need two ways to do it! Empowering Programming Languages Bloat and Retrofuturism Refreshing my Blog Again Random Rust Impressions Apilar: An Alife System I Was a 1980s Teenage Programmer Part 2: Olivetti M24 I Was a 1980s Teenage Programmer: the Alphatronic SolidJS fits my brain Is premature optimization the root of all evil? Framework Patterns: JavaScript edition Roll Your Own Frameworks Framework Patterns Secret Weblog Highlights Refactoring to Multiple Exit Points mstform: a form library for mobx-state-tree Seven Years: A Very Personal History of the Web Morepath 0.16 released! Is Morepath Fast Yet? Introducing Bob Strongpinion Punctuated Equilibrium in Software Morepath 0.15 released! Impressions of React Europe 2016 Morepath 0.14 released! Morepath 0.13 now with Dectate Dectate: advanced configuration for Python code JavaScript Dependencies Revisited: An Example Project The Incredible Drifting Cyber A Brief History of Reselect The Emerging GraphQL Python stack Thoughts about React Europe Build a better batching UI with Morepath and Jinja2 GraphQL and REST Server Templating in Morepath 0.10 10 reasons to check out the Morepath web framework in 2015 A Review of the Web and how Morepath fits in Morepath 0.9 released! Better REST with Morepath 0.8 Morepath 0.7: new inter-app linking They say something I don Life at the Boundaries: Conversion and Validation BowerStatic 0.4 released! Morepath 0.6 released! Morepath 0.5(.1) and friends released! New HTTP 1.1 RFCs versus WSGI Against On Naming In Open Source My visit to EuroPython 2014 Morepath 0.4.1 released (with Python 3 fixes) Morepath 0.4 and breaking changes Announcing BowerStatic Morepath 0.3 released! Morepath 0.2 Morepath Python 3 support The Call of Python 2.8 Morepath 0.1 released! WebOb and Werkzeug compared Morepath: from Werkzeug to WebOb Racing the Morepath: SQLAlchemy Integration The Centre Cannot Hold Breaking Morepath Changes Morepath Update How to do REST with Morepath Morepath Security the Gravity of Python 2 #python2.8 discussion channel on freenode Alex Gaynor on Python 3 Morepath Documentation Starting to Take Shape Back to the Center Morepath App Reuse Implementing Grok Grok: the Idea Why Linux Works for Me Reg, Now With More Generic! The New Zope as a Web Framework Jim Fulton, Zope Architect Renewing Zope Object Publishing The Weirdness of Zope The Rise of Zope My Exit from Zope Reg: Component Architecture Reimagined JSConf EU 2013 impressions Obviel 1.0! JS Dependency Tools Redux Obviel 1.0rc1 released! Succinct data structures
On the Morepath
Martijn Faassen · 2013-10-31 · via Secret Weblog

Introduction

For a while now I've been working on Morepath. I thought I'd say a bit about it here.

Morepath is a Python web micro-framework with super powers. It looks much like your average Python micro-framework, but it packs some seriously power beneath the hood.

Web micro-framework battle wiki!

Let's start with sample code, a wiki implementation:

https://github.com/morepath/morepath_wiki/blob/master/mpwiki/wiki.py

This code is based on an example devised by Richard Jones for his web micro-framework battle presentation. When I asked him, he kindly shared his codebase with implementations for various micro-frameworks.

The Morepath wiki code uses the reusable module storage.py that Richard created which implements the wiki backend and page rendering. This is actually a little bit unfortunate for Morepath, as storage.py doesn't expose an object oriented API. There is no wiki Page class for instance, so I had to come up with a simple one myself, as Morepath is very model-driven. Perhaps I'll refactor storage.py in the future so I can better show off how Morepath can empower your models.

Configuration

Morepath at first sight looks quite a bit like a Flask application. You create an application object. You then use methods on the application object as decorators to configure it.

But there is a significant difference with Flask (or many other web frameworks, including Django) in that loading the configuration is not a import-time side-effect, but an explict step. Morepath is like Zope and Pyramid in this respect. The Pyramid documentation has an extensive section explaining why this is a good thing.

Routing to Models

Morepath's routing is different from any routing web framework I've encountered before. Morepath routes to models, not to views. In the wiki example the route to the wiki page model is done like this:

@app.model(model=Page, path='{name}',
           variables=lambda model: {'name': model.name})
def get_page(name):
    if not storage.wikiname_re.match(name):
        return None
    return Page(name)

This says that paths like /foo go to a Page object with the name foo. If no such wiki page exists, we return None, which will result in a 404 error.

Views

The routing code where the model is looked up is completely separate from presentation. That's done in the view. Here's the default view for Page (i.e. /FrontPage):

@app.html(model=Page)
def display(request, model):
    return wiki.render_page(model.name)

And here is the edit view (i.e. /FrontPage/edit):

@app.html(model=Page, name='edit', request_method='GET')
def edit_form(request, model):
    return wiki.render_edit_form(model.name)

Because Morepath routes to models, it can construct a link for a model, which we see demonstrated for instance in a redirect response:

return redirect(request.link(model))

request.link() receives a model and optionally a view name. Using the variables argument on the @app.model decorator it can reconstruct the path for you from the model. You don't need to remember route names or what parameters go into them. Your links will continue to work if you change your app's routes completely.

Reuse and Flexibility

Morepath is powered by the generic function library Reg. This provides a general mechanism for composing, extending and overriding behavior.

In the wiki example, the Page model has a default display view, and edit and history views. If you were to create a subclass from Page called DiscussionPage, instances of DiscussionPage would automatically share these views. But you can specialize: if you want your DiscussionPage model to have a special way to display itself but still share edit and history, this is what you'd do:

@app.html(model=DiscussionPage)
def discussion_display(request, model):
    return "<h2>A different discussion page!</h2>"

With Morepath, you can bundle a set of behaviors such as views (and routes) in a custom framework application, and then let others reuse it in their own applications. But if in the same run-time you want to have another application that doesn't share any of this behavior, Morepath lets you do this too.

That's a lot of power in a small package. It's in fact a condensation of 15 years of my experience with Zope packed together into a micro-framework.

Development Status

I'm actively developing Morepath and looking for feedback. Documentation is very scarce right now, but that situation won't continue for long.

The Morepath code is here:

https://github.com/morepath/morepath

At PyCon DE earlier this month I gave a keynote speech where I go into some of the creative process and thinking behind Morepath. If you have more than an hour to spare, you can watch it.

There's an IRC channel, #morepath on freenode. Hope to see you there!