如何在BottlePy模板中加载JavaScript或CSS文件?
我正在使用BottlePy返回一个HTML模板,这个过程很顺利。但是当我在我的模板文件中插入一个JavaScript文件时,情况就不太好了:
<script type="text/javascript" src="js/main.js" charset="utf-8"></script>
我收到了一个404错误。 (无法加载资源:服务器返回了404状态(未找到))
有没有人知道怎么解决这个问题?
这是我的脚本文件:
from bottle import route, run, view
@route('/')
@view('index')
def index():
return dict()
run(host='localhost', port=8080)
这个模板文件位于"./views"子文件夹中。
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8" />
<script type="text/javascript" src="js/main.js" charset="utf-8"></script>
</head>
<body>
</body>
</html>
也许是开发服务器在寻找我的js文件时,路径写成了"rootPath/js/main.js"?
文件的结构是:
app.py
-js
main.js
-views
index.tpl
谢谢。
3 个回答
我觉得你把文件 main.js
放错地方了。
要注意,这个文件的路径应该是相对于你请求的网页地址,而不是相对于你模板的路径。所以把它放在像 template/js/main.js
这样的文件夹里是行不通的。
这里介绍了一种在Bottle网页项目中添加静态文件(比如CSS和JS)的有效方法。我使用的是Bootstrap和Python 3.6。
项目结构
project
│ app.py
│ bottle.py
│
├───static
│ └───asset
│ ├───css
│ │ bootstrap-theme.css
│ │ bootstrap-theme.css.map
│ │ bootstrap-theme.min.css
│ │ bootstrap-theme.min.css.map
│ │ bootstrap.css
│ │ bootstrap.css.map
│ │ bootstrap.min.css
│ │ bootstrap.min.css.map
│ │ custom.css
│ │
│ ├───fonts
│ │ glyphicons-halflings-regular.eot
│ │ glyphicons-halflings-regular.svg
│ │ glyphicons-halflings-regular.ttf
│ │ glyphicons-halflings-regular.woff
│ │ glyphicons-halflings-regular.woff2
│ │
│ └───js
│ bootstrap.js
│ bootstrap.min.js
│ jquery.min.js
│ npm.js
│
└───views
index.tpl
app.py
from bottle import Bottle, run, \
template, debug, static_file
import os, sys
dirname = os.path.dirname(sys.argv[0])
app = Bottle()
debug(True)
@app.route('/static/<filename:re:.*\.css>')
def send_css(filename):
return static_file(filename, root=dirname+'/static/asset/css')
@app.route('/static/<filename:re:.*\.js>')
def send_js(filename):
return static_file(filename, root=dirname+'/static/asset/js')
@app.route('/')
def index():
data = {"developer_name":"Ahmedur Rahman Shovon",
"developer_organization":"Datamate Web Solutions"}
return template('index', data = data)
run(app, host='localhost', port = 8080)
index.tpl
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Bottle web project template">
<meta name="author" content="datamate">
<link rel="icon" href="/static/favicon.ico">
<title>Project</title>
<link rel="stylesheet" type="text/css" href="/static/bootstrap.min.css">
<script type="text/javascript" src="/static/jquery.min.js"></script>
<script type="text/javascript" src="/static/bootstrap.min.js"></script>
</head>
<body>
<!-- Static navbar -->
<nav class="navbar navbar-default navbar-static-top">
<div class="container">
<div class="row">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Project</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="../navbar/">Home</a></li>
<li><a href="./">Github</a></li>
<li><a href="../navbar-fixed-top/">Stackoverflow</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
</nav>
<div class="container">
<div class="row">
<div class="jumbotron">
<h2>Welcome from {{data["developer_name"]}}</h2>
<p>This is a template showcasing the optional theme stylesheet included in Bootstrap. Use it as a starting point to create something more unique by building on or modifying it.</p>
</div>
</div>
<!--./row-->
<div class="row">
<hr>
<footer>
<p>© 2017 {{data["developer_organization"]}}.</p>
</footer>
</div>
</div>
<!-- /container -->
</body>
</html>
输出效果
首先,你需要确保你的开发服务器能够提供 main.js
文件,否则浏览器就无法找到它。
在小型网页应用中,通常会把所有的 .js
和 .css
文件放在一个叫 static
的文件夹里,所以你的文件结构应该像这样:
app.py
- static/
main.js
- views/
index.tpl
不过,这种命名和结构并不是必须的,只是常见的做法。
接下来,你需要为静态文件设置一个处理器:
from bottle import static_file
# ...
@route('/static/:path#.+#', name='static')
def static(path):
return static_file(path, root='static')
这样就能把 static/
文件夹里的文件提供给浏览器了。
然后,我们来看看最后一件事。你在代码中指定了你的 JavaScript 文件路径:
<script type="text/javascript" src="js/main.js" charset="utf-8"></script>
这意味着 .js
文件的路径是相对于当前页面的。在你的开发服务器上,首页(/
)会在 /js/main.js
找到 .js
文件,而其他页面(比如 /post/12
)会在 /post/12/js/main.js
找到它,这样肯定会失败。
所以,你需要使用 get_url
函数来正确引用静态文件。你的处理器应该像这样:
from Bottle import get_url
# ...
@route('/')
@view('index')
def index():
return { 'get_url': get_url }
在 index.tpl
文件中,.js
应该这样引用:
<script type="text/javascript" src="{{ get_url('static', path='main.js') }}" charset="utf-8"></script>
get_url
会找到一个处理器,名称为 name='static'
,并计算出正确的路径。对于开发服务器来说,这个路径总是 /static/
。你甚至可以在模板中直接写死这个路径,但我不推荐这样做,原因有两个:
- 你在生产环境中不能把应用放在根目录以外的地方;也就是说,当你把它上传到生产服务器时,它可能会放在 http://example.com/(根目录),但不能放在 http://example.com/myapp/。
- 如果你改变了
/static/
文件夹的位置,你就得在所有模板中找到并修改这个路径,工作量会很大。