简体   繁体   English

瓶静态文件

[英]Bottle Static files

I have tried reading the docs for Bottle, however, I am still unsure about how static file serving works. 我曾尝试阅读Bottle的文档,但是,我仍然不确定静态文件服务是如何工作的。 I have an index.tpl file, and within it it has a css file attached to it, and it works. 我有一个index.tpl文件,并在其中附加了一个css文件,它的工作原理。 However, I was reading that Bottle does not automatically serve css files, which can't be true if the page loads correctly. 但是,我正在读取Bottle不会自动提供css文件,如果页面正确加载则不能为true。

I have, however, run into speed issues when requesting the page. 但是,在请求页面时,我遇到了速度问题。 Is that because I didn't use the return static_file(params go here) ? 那是因为我没有使用return static_file(params go here) If someone could clear up how they work, and how they are used when loading the page, it would be great. 如果有人能够清理它们的工作方式,以及在加载页面时如何使用它们,那就太棒了。

Server code: 服务器代码:

from Bottle import route,run,template,request,static_file



@route('/')
def home():
    return template('Templates/index',name=request.environ.get('REMOTE_ADDR'))

run(host='Work-PC',port=9999,debug=True)

Index: 指数:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta http-equiv="content-type"
 content="text/html; charset=ISO-8859-1">
  <title>index</title>
  <link type="text/css"
 href="cssfiles/mainpagecss.css"
 rel="stylesheet">
</head>
<body>
<table
 style="width: 100%; text-align: left; margin-left: auto; margin-right: auto;"
 border="0" cellpadding="2" cellspacing="2">
  <tbody>
    <tr>
      <td>
      <h1><span class="headertext">
      <center>Network
Website</center>
      </span></h1>
      </td>
    </tr>
  </tbody>
</table>
%if name!='none':
    <p align="right">signed in as: {{name}}</p>
%else:
    pass
%end
<br>
<table style="text-align: left; width: 100%;" border="0" cellpadding="2"
 cellspacing="2">
  <tbody>
    <tr>
      <td>
      <table style="text-align: left; width: 100%;" border="0"
 cellpadding="2" cellspacing="2">
        <tbody>
          <tr>
            <td style="width: 15%; vertical-align: top;">
            <table style="text-align: left; width: 100%;" border="1"
 cellpadding="2" cellspacing="2">
              <tbody>
                <tr>
                  <td>Home<br>
                  <span class="important">Teamspeak Download</span><br>
                  <span class="important">Teamspeak Information</span></td>
                </tr>
              </tbody>
            </table>
            </td>
            <td style="vertical-align: top;">
            <table style="text-align: left; width: 100%;" border="1"
 cellpadding="2" cellspacing="2">
              <tbody>
                <tr>
                  <td>
                  <h1><span style="font-weight: bold;">Network Website</span></h1>
To find all of the needed information relating to the network's social
capabilities, please refer to the links in the side bar.</td>
                </tr>
              </tbody>
            </table>
            </td>
          </tr>
        </tbody>
      </table>
      </td>
    </tr>
  </tbody>
</table>
</body>
</html>

To serve static files using bottle you'll need to use the provided static_file function and add a few additional routes. 要使用bottle提供静态文件,您需要使用提供的static_file函数并添加一些其他路由。 The following routes direct the static file requests and ensure that only files with the correct file extension are accessed. 以下路由指示静态文件请求,并确保仅访问具有正确文件扩展名的文件。

from bottle import get, static_file

# Static Routes
@get("/static/css/<filepath:re:.*\.css>")
def css(filepath):
    return static_file(filepath, root="static/css")

@get("/static/font/<filepath:re:.*\.(eot|otf|svg|ttf|woff|woff2?)>")
def font(filepath):
    return static_file(filepath, root="static/font")

@get("/static/img/<filepath:re:.*\.(jpg|png|gif|ico|svg)>")
def img(filepath):
    return static_file(filepath, root="static/img")

@get("/static/js/<filepath:re:.*\.js>")
def js(filepath):
    return static_file(filepath, root="static/js")

Now in your html, you can reference a file like so: 现在在你的html中,你可以像这样引用一个文件:

<link type="text/css" href="/static/css/main.css" rel="stylesheet">

Directory layout: 目录布局:

`--static
|  `--css
|  `--fonts
|  `--img
|  `--js

Just providing an answer here because a number of my students have used this code in an assignment and I have a bit of a concern about the solution. 这里只是提供一个答案,因为我的一些学生在作业中使用了这段代码,我对解决方案有点担心。

The standard way to serve static files in Bottle is in the documentation : 在Bottle中提供静态文件的标准方法是在文档中

from bottle import static_file
@route('/static/<filepath:path>')
def server_static(filepath):
    return static_file(filepath, root='/path/to/your/static/files')

in this way, all of the files below your static folder are served from a URL starting with /static. 这样,静态文件夹下的所有文件都是从以/ static开头的URL提供的。 In your HTML, you need to reference the full URL path for the resource, eg: 在HTML中,您需要引用资源的完整URL路径,例如:

<link rel='stylesheet' type='text/css' href='/static/css/style.css'>

The answer from Sanketh makes it so that any reference to an image, css file etc anywhere in the URL space is served from a given folder inside the static folder. Sanketh的答案使得对于URL空间中任何位置的图像,css文件等的任何引用都是从静态文件夹内的给定文件夹提供的。 So /foo/bar/baz/picture.jpg and /picture.jpg would both be served from static/images/picture.jpg. 所以/foo/bar/baz/picture.jpg和/picture.jpg都将由static / images / picture.jpg提供。 This means that you don't need to worry about getting the path right in your HTML code and you can always use relative filenames (ie. just src="picture.jpg"). 这意味着您无需担心在HTML代码中获取正确的路径,并且您始终可以使用相对文件名(即只是src =“picture.jpg”)。

The problem with this approach comes when you try to deploy your application. 当您尝试部署应用程序时,会出现此方法的问题。 In a production environment you want the static resources to be served by a web server like nginx, not by your Bottle application. 在生产环境中,您希望静态资源由nginx等Web服务器提供,而不是由Bottle应用程序提供。 To enable this, they should all be served from a single part of the URL space, eg. 为了实现这一点,它们应该从URL空间的单个部分提供,例如。 /static. /静态的。 If your code is littered with relative filenames, it won't translate easily to this model. 如果您的代码中包含相对文件名,则无法轻松转换为此模型。

So, I'd advise using the three line solution from the Bottle tutorial rather than the more complex solution listed on this page. 因此,我建议使用Bottle教程中的三行解决方案,而不是本页列出的更复杂的解决方案。 It's simpler code (so less likely to be buggy) and it allows you to seamlessly move to a production environment without code changes. 它的代码更简单(因此不太可能出错)并且它允许您无需更改代码即可无缝移动到生产环境。

As indicated in the documentation, you should serve static files using the static function and css is a static file. 如文档中所示,您应该使用静态函数提供静态文件,而css是一个静态文件。 The static function handles security and some other function which you can find out from the source. 静态函数处理安全性以及您可以从源中找到的其他一些功能。 The path argument to the static function should point to the directory wherever you store the css files 静态函数的path参数应指向存储css文件的目录

Rather than use regular expression matching for serving files as in Sanketh's answer, I'd prefer not to modify my templates and provide a path to the static files explicitly, as in: 我不想像在Sanketh的回答中那样使用正则表达式匹配服务文件,而是不修改模板并明确提供静态文件的路径,如:

<script src="{{ get_url('static', filename='js/bootstrap.min.js') }}"></script>

You can do this simply by replacing the <filename> in the static route decorator with one of type :path - like so: 你可以简单地通过将静态路由装饰器中的<filename>替换为类型:path - 就像这样:

@app.route('/static/<filename:path>', name='static')
def serve_static(filename):
    return static_file(filename, root=config.STATIC_PATH)

The :path matches an entire file path in a non-greedy way so you don't have to worry about changing templates when switching to production - just keep everything in the same relative folder structure. :path以非贪婪的方式匹配整个文件路径,因此您不必担心在切换到生产时更改模板 - 只需将所有内容保存在相同的相对文件夹结构中。

I've used Sanketh's template in the past but over time condensed it to an extension agnostic function. 我过去曾使用Sanketh的模板,但随着时间的推移将其浓缩为扩展不可知功能。 You just have to add extension-folder mappings in the ext_map dictionary. 您只需在ext_map字典中添加扩展名文件夹映射。 It defaults to static/ folder if an extension is not mapped explicitly. 如果未明确映射扩展,则默认为static / folder。

import os.path    

# Static Routes
@get('/<filename>')
def serve_static_file(filename):
    ext = os.path.splitext(filename)[1][1:]
    ext_map = {'image':['png','gif','jpg','ico'],'js':['js']}
    sub_folder = next((k for k, v in ext_map.items() if ext in v),'')
    return static_file(filename, root='static/'+sub_folder)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM