Python:使用Flask构建可写主题网站

0 投票
1 回答
993 浏览
提问于 2025-04-17 17:06

我正在用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 个回答

2

我知道这个问题是一年前问的,但这个问题现在依然存在。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')

这也可以通过其他方式扩展,比如用户会话、数据库配置等等。

希望这能帮助到某些人。

撰写回答