micro - flask python 2
Archivos estáticos de botella (5)
Como se indica en la documentación, debe servir archivos estáticos usando la función estática y css es un archivo estático. La función estática maneja la seguridad y alguna otra función que puede encontrar desde la fuente. El argumento de la ruta a la función estática debe apuntar al directorio dondequiera que guarde los archivos css
He intentado leer los documentos de Bottle, sin embargo, todavía no estoy seguro de cómo funciona la publicación de archivos estáticos. Tengo un archivo index.tpl
, y dentro de él tiene un archivo css adjunto, y funciona. Sin embargo, estaba leyendo que Bottle no sirve automáticamente archivos css, lo que no puede ser cierto si la página se carga correctamente.
Sin embargo, he tenido problemas de velocidad al solicitar la página. ¿Es eso porque no return static_file(params go here)
el return static_file(params go here)
? Si alguien pudiera aclarar cómo funcionan y cómo se usan al cargar la página, sería genial.
Código del servidor:
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)
Índice:
<!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>
En lugar de utilizar la coincidencia de expresiones regulares para servir archivos como en la respuesta de Sanketh, preferiría no modificar mis plantillas y proporcionar una ruta a los archivos estáticos explícitamente, como en:
<script src="{{ get_url(''static'', filename=''js/bootstrap.min.js'') }}"></script>
Puede hacer esto simplemente reemplazando el <filename>
en el decorador de rutas estáticas por uno de tipo :path
, como por ejemplo:
@app.route(''/static/<filename:path>'', name=''static'')
def serve_static(filename):
return static_file(filename, root=config.STATIC_PATH)
La :path
coincide con una ruta de archivo completa de una manera no codiciosa, por lo que no tiene que preocuparse por cambiar las plantillas al cambiar a producción, simplemente mantenga todo en la misma estructura de carpetas relativa.
He utilizado la plantilla de Sanketh en el pasado, pero con el tiempo la he condensado en una función independiente de la extensión. Solo tiene que agregar asignaciones de carpeta de extensión en el diccionario ext_map. Su valor predeterminado es static / folder si una extensión no está asignada explícitamente.
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)
Para servir archivos estáticos utilizando una bottle
, deberá usar la función static_file
proporcionada y agregar algunas rutas adicionales. Las siguientes rutas dirigen las solicitudes de archivos estáticos y garantizan que solo se acceda a los archivos con la extensión de archivo correcta.
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")
Ahora en tu html, puedes hacer referencia a un archivo así:
<link type="text/css" href="/static/css/main.css" rel="stylesheet">
Diseño del directorio:
`--static
| `--css
| `--fonts
| `--img
| `--js
Solo ofrezco una respuesta aquí porque varios de mis alumnos han usado este código en una tarea y me preocupa un poco la solución.
La forma estándar de servir archivos estáticos en Bottle se encuentra en 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 esta forma, todos los archivos debajo de su carpeta estática se sirven desde una URL que comienza con / static. En su HTML, necesita hacer referencia a la ruta completa de la URL para el recurso, por ejemplo:
<link rel=''stylesheet'' type=''text/css'' href=''/static/css/style.css''>
La respuesta de Sanketh hace que cualquier referencia a una imagen, archivo css, etc. en cualquier parte del espacio URL se sirva desde una carpeta determinada dentro de la carpeta estática. Entonces /foo/bar/baz/picture.jpg y /picture.jpg ambos se publicarán desde static / images / picture.jpg. Esto significa que no necesita preocuparse por obtener la ruta correcta en su código HTML y siempre puede usar nombres de archivo relativos (es decir, simplemente src = "picture.jpg").
El problema con este enfoque viene cuando intentas implementar tu aplicación. En un entorno de producción, desea que los recursos estáticos sean atendidos por un servidor web como nginx, no por su aplicación de botella. Para habilitar esto, deben ser servidos desde una sola parte del espacio URL, ej. /estático. Si su código está lleno de nombres de archivo relativos, no se traducirá fácilmente a este modelo.
Por lo tanto, aconsejaría utilizar la solución de tres líneas del tutorial de Bottle en lugar de la solución más compleja que figura en esta página. Es un código más simple (por lo que es menos probable que tenga errores) y le permite pasar sin problemas a un entorno de producción sin cambios de código.