Python:使用Flask构建可写主题网站
我正在用Python的Flask框架写一个网站,但遇到了一些问题。我的目标是让每个用户都能写自己的主题。我已经解决了主题引擎的部分,但接下来就是目录的问题。
大家都知道,在Flask中有两个目录,一个叫templates
,另一个叫static
。当用户上传他们的主题时,我应该把它放到templates
里还是static
里呢?
用户上传的主题里有assets(比如js等)
和html
文件。如果我把它们放到templates
目录里,就无法访问css、js等
文件了。
反过来,如果我把它们放到static
文件夹里,jinja2(Flask用来处理模板的工具)就找不到html
文件了,还有人说不要把html
文件放到静态文件夹里。
那我该怎么办呢?我是不是应该再加一个叫userthemes
的文件夹?
现在,我的目录结构是这样的:
/python
/static
/templates
login.html
admin_page.html
app.py
当用户上传他们的主题时,index.html
会出现。如果你能帮忙,我会很感激。谢谢。
1 个回答
我知道这个问题是一年前问的,但这个问题现在依然存在。Flask-Themes到现在都没法用,所以我不得不自己找办法。
其实这个过程很简单。
保持一个干净的结构是后续维护的必要条件(即使这个项目只有一个作者)。
所以,我尝试调整Özcan的结构,以便有多个模板配置,我们可以有这样的结构:
/python
_ _ _ _app.py
_ _ _ _config.py
______/templates
________________/default
_ _ _ _ _ _ _ _ _ _ _ _index.html
________________/custom
_ _ _ _ _ _ _ _ _ _ _ _index.html
我不知道他应用文件里的代码是什么,但我假设在app.py里有这样的内容:
from flask import Flask, render_template
import config
app = Flask(__name__, template_folder='/templates/' + config.Config.ACTIVE_THEME)
@app.route('/')
def main():
return render_template('index.html')
if '__name__' == '__main__':
app.run()
config.py可以这样写:
class Config(object):
ACTIVE_THEME='default'
在templates文件夹里的default主题的index.html可能看起来是这样的:
<head>
# We have the ability to include the css from the current path instead of having a separate static folder
<style type='text/css'> {% include 'style.css' %} </style>
</head>
<body>
<h1> This is the "default" theme </h1>
</body>
而custom主题的index.html可能是这样的:
<head>
<style type='text/css'> {% include 'style.css' %} </style>
</head>
<body>
<h1> This is the "custom" theme </h1>
</body>
现在,访问 127.0.0.1:5000
会显示“这是默认主题”,因为实际上加载的是默认主题。
要更改这个,你需要按照以下方式编辑配置文件:
class Config(object):
# Set ACTIVE_THEME from default to custom
ACTIVE_THEME='custom'
保存更改,刷新页面,你应该能看到“这是自定义主题”。
这只是一个非常基础的“技巧”,但如果你对你的应用比较认真,我建议使用蓝图(blueprints),而且这样的话,你还得维护两个配置文件,而不是一个。
为了避免这些问题,我使用蓝图和良好的应用结构。
例如,我在应用初始化后定义配置,所以不是这样:
import config
app = Flask(__name__, template_folder=/templates/' + config.Config.ACTIVE_THEME)
而是这样:
app = Flask(__name__)
app.config.from_object('config.Config')
在一个单独的文件中,所有视图的顶部加上以下一行:
# doing an "import app" would raise an error because of it being a circular import
import config
active_theme = config.Config.ACTIVE_THEME
# Watch out for the second argument as it seems to add a prefix to successive defined arguments. In fact you could swap the "themes" part to it and remove it from the third argument, but I prefer to leave it like this to avoid future headaches.
posts = Blueprint('posts', '', template_folder='templates/' + active_theme + '/post')
这也可以通过其他方式扩展,比如用户会话、数据库配置等等。
希望这能帮助到某些人。