Bouteille fichiers statiques

J'ai essayé de lire les documents pour Bottle, cependant, je ne suis toujours pas sûr du fonctionnement du service de fichiers statiques. J'ai un fichier index.tpl, et à l'intérieur il y a un fichier css attaché, et cela fonctionne. Cependant, je lisais que Bottle ne sert pas automatiquement les fichiers css, ce qui ne peut pas être vrai si la page se charge correctement.

J'ai cependant rencontré des problèmes de vitesse lors de la demande de la page. Est-ce parce que je n'ai pas utilisé le return static_file(params go here)? Si quelqu'un pouvait clarifier comment ils fonctionnent, et comment ils sont utilisé lors du chargement de la page, ce serait formidable.

Code du serveur:

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>
23
demandé sur Magnus Lind Oxlund 2012-05-07 21:16:00

5 réponses

Comme indiqué dans la documentation, vous devez servir des fichiers statiques en utilisant statique Fonction et css est un fichier statique. La fonction statique gère la sécurité et une autre fonction que vous pouvez trouver à partir de la source. Le chemin argument à la fonction statique doit pointer vers le répertoire où vous stockez les css fichiers

2
répondu cobie 2012-05-07 18:44:34

Pour servir des fichiers statiques en utilisant bottle, vous devrez utiliser la fonction static_file fournie et ajouter quelques routes supplémentaires. Les itinéraires suivants dirigent les demandes de fichiers statiques et garantissent que seuls les fichiers avec l'extension de fichier correcte sont accessibles.

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")

Maintenant, dans votre html, vous pouvez référencer un fichier comme ceci:

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

Disposition du répertoire:

`--static
|  `--css
|  `--fonts
|  `--img
|  `--js
71
répondu Sanketh Katta 2018-05-16 03:05:53

Juste fournir une réponse ici parce qu'un certain nombre de mes étudiants ont utilisé ce code dans une tâche et j'ai un peu d'inquiétude au sujet de la solution.

La manière standard de servir les fichiers statiques dans Bottle se trouve dans la documentation :

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

De cette façon, tous les fichiers sous votre dossier statique sont servis à partir d'une URL commençant par /static. Dans votre HTML, vous devez référencer le chemin D'URL complet de la ressource, par exemple:

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

La réponse de Sanketh fait en sorte que toute référence à une image, fichier css etc n'importe où dans L'espace URL est servi à partir d'un dossier donné dans le dossier statique. Alors / foo / bar / baz / image.jpg et /image.jpg serait à la fois servi de statique / images / Image.jpg. Cela signifie que vous n'avez pas besoin de vous soucier d'obtenir le bon chemin dans votre code HTML et vous pouvez toujours utiliser des noms de fichiers relatifs (ie. juste src="image.jpg").

Le problème avec cette approche vient lorsque vous essayez de déployer votre application. Dans un environnement de production vous voulez que les ressources statiques soient servies par un serveur web comme nginx, pas par votre application Bottle. Pour activer cela, ils doivent tous être servis à partir d'une seule partie de l'espace URL, par exemple. /statique. Si votre code est jonché de noms de fichiers relatifs, il ne se traduira pas facilement vers ce modèle.

Donc, je vous conseille d'utiliser la solution à trois lignes du tutoriel de la bouteille plutôt que la solution plus complexe répertoriée sur cette page. C'est un code plus simple (donc moins susceptible d'être bogué) et il vous permet de passer de manière transparente à un environnement de production sans modifications de code.

9
répondu Steve Cassidy 2016-06-08 01:55:08

Plutôt que d'utiliser la correspondance d'expression régulière pour servir les fichiers comme dans la réponse de Sanketh, je préférerais ne pas modifier mes modèles et fournir explicitement un chemin vers les fichiers statiques, comme dans:

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

, Vous pouvez le faire simplement en remplaçant les <filename> dans l'itinéraire statique décorateur: l'une de type :path comme:

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

Le :path correspond à un chemin de fichier entier d'une manière non gourmande afin que vous n'ayez pas à vous soucier de changer de modèle lors du passage à la production-gardez tout dans la même structure de dossier relative.

3
répondu Aaron D 2015-07-28 03:06:29

J'ai utilisé le modèle de Sanketh dans le passé, mais au fil du temps condensé à une fonction agnostique d'extension. Il vous suffit d'ajouter des mappages de dossier d'extension dans le dictionnaire ext_map. Il est par défaut static / folder si une extension n'est pas mappée explicitement.

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)
1
répondu phoxley 2015-07-25 00:54:25