Статические файлы не загружаются в приложение Bottle, когда завершающий слеш опущен - PullRequest
2 голосов
/ 29 февраля 2012

Я передаю тестовый файл через Apache, используя Bottle.

Ниже приведены мои настройки Apache:

WSGIDaemonProcess temp user=www-data group=www-data processes=1 threads=5
WSGIScriptAlias /temp /opt/gridops/usage/temp/adapter.wsgi

<Directory /opt/gridops/usage/temp>
        WSGIProcessGroup temp
        WSGIApplicationGroup %{GLOBAL}
        Order deny,allow
        Allow from all
</Directory>

adapter.wsgi:

import os,sys
os.chdir(os.path.dirname(__file__))
sys.path = ['/opt/gridops/usage/temp'] + sys.path
os.chdir(os.path.dirname(__file__))
sys.stdout = sys.stderr
import bottle
print "++"*10
import index # This loads your application
application = bottle.default_app()

index.py:

from bottle import mount, run 
from routes import app
from bottle import default_app
default_app.push(app)
#run()
#run(app=app, host='192.168.1.3', port=8085) 

routes.py:

from bottle import Bottle , run,route,static_file,view,template,post,request

app = Bottle()
print str(dir(app))
@app.route('/static/<filename>')
def server_static(filename):
    return static_file(filename, root='static')

@app.route('/') 
def index(): 
        return template('template',text='This is index page!')

template.tpl:

<html>
<head>

<link rel="stylesheet" type="text/css" href="static/prettify.css" />
</head>
<body>
{{text}}
</body>

</html>

Список каталогов

temp/
  adapter.wsgi
  index.py
  routes.py
  static/
     prettify.css
  views/
     template.tpl

Моя проблема - всякий раз, когда я пытаюсь получить доступ к приложению Бутылка с помощью http://192.168.1.3/temp, веб-страница отображается без статических файлов, но всякий раз, когда я получаю доступ к http://192.168.1.3/temp/ [Обратите внимание на дополнительные /], страница загружается правильно.Какую модификацию я должен сделать так, чтобы результаты как http://192.168.1.3/temp, так и http://192.168.1.3/temp/ стали одинаковыми?

Любая помощь будет очень полезна

Ответы [ 3 ]

14 голосов
/ 02 марта 2012

Проблема

Проблемная строка такая:

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

Адрес файла CSS является относительным, поэтому полный абсолютный адрес вычисляется из местоположения загруженной страницы.

Для http://192.168.1.3/temp/ это будет http://192.168.1.3/temp/static/prettify.css (правильно).

Для http://192.168.1.3/temp это будет http://192.168.1.3/static/prettify.css.temp считается файлом в корневом каталоге, а не отдельным подкаталогом.

Решение

Не существует приемлемого способа использовать один относительный адрес для ссылки настатические ресурсы.Ваше приложение, скорее всего, будет иметь «вложенные» пути, такие как /article/some-name, или /view/content/566, или что-то вроде этого, а также такие простые пути, как /.

. Вы можете попытаться указать root-на основе пути, например /temp/static/prettify.css, в вашем шаблоне, но это означает, что вам придется изменить шаблон, если вы переместите само приложение (скажем, на myapp.example.com/ с example.com/myapp/).

Вместо этого выНужно указать платформе, чтобы сделать правильный путь к ресурсу, который нужно использовать.У бутылки есть функция с именем get_url , чтобы облегчить это.К сожалению, это не упоминается в уроках по бутылкам.

Код

Вот что вы должны сделать.

В template.tpl, позвоните get_url, ссылаясь на статический обработчик:

<link rel="stylesheet" type="text/css" 
      href="{{ get_url('static', filename='prettify.css') }}" />

В routes.py, импорт get_url:

from bottle import Bottle, run, route, static_file, view, template, 
                   post, request, get_url

Затем назовите ваш обработчик, чтобы вы могли передать его имя get_url:

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

Наконец, укажите фактический get_url в качестве аргумента шаблона при рендеринге шаблона:

@app.route('/') 
def index(): 
    return template('template', text='This is index page!', get_url=get_url)

В качестве альтернативы, вместо предоставления get_url в каждом обработчике, установите шаблон по умолчанию в index.py:

from Bottle import SimpleTemplate
SimpleTemplate.defaults["get_url"] = app.get_url

Предупреждение : последний способ, по-видимому, недокументирован, но объяснен автором бутылки в списке рассылки .

Заключительная мысль

Поскольку каждая страница на сайте должна иметь канонический адрес, вы можете выбрать одну форму (с косой чертой или без нее) в качестве канонической и добавить какой-либо вид перенаправления с другойодин.

1 голос
/ 14 октября 2014

Другим обходным решением является добавление этого перенаправления в файл конфигурации Apache:

RedirectMatch 301 ^/(temp)$ /$1/

Это добавит / в конце вашей индексной страницы, поэтому вам не нужно изменять ваш код.

0 голосов
/ 05 марта 2014

Один обходной путь должен добавить:

<base href="/temp/">

к голове в шаблоне.

...