У меня есть приложение, которое я пишу с использованием CherryPy, HTML-шаблонов Mako и JavaScript. Я хочу разрешить его установку на любой URL-адрес, то есть я хочу, чтобы кто-то мог установить его на http://example.com или http://example.com/app или http://this.is.an.example.com/some/application/whatever . Я также хочу, чтобы оно работало так же хорошо, как приложение WSGI за Apache или с использованием встроенного веб-сервера CherryPy. Однако у меня возникают проблемы с URL-адресами, которые должны использовать мои шаблоны и JavaScript.
То есть, если я хочу получить доступ к ресурсу, относящемуся к корневому каталогу моего приложения, например api/something
или static/application.js
, как я могу убедиться, что ссылка будет работать независимо от базового URL-адреса моего приложения?
Моим первоначальным наивным решением было использование относительных URL-адресов, но оно перестало работать, когда я захотел вернуть один и тот же шаблон Mako на несколько конечных точек. То есть, если у меня есть шаблон, используемый для отображения элемента, возможно, я захочу отобразить этот элемент где-то на странице в корне (/
), а может быть, и еще где-нибудь (например, может быть, /item
, а может быть, и /username/items
). Если в шаблоне есть относительный URL-адрес, этот URL-адрес является относительным этого местоположения. Это означает, что, поскольку мои статические ресурсы CSS/JS/изображения относятся только к корневому каталогу, ссылки будут разорваны для шаблоны в местах /item
и /username/items
.
Мако шаблоны
Я обнаружил, что могу обернуть свои URL-адреса в cherrypy.url()
в своих шаблонах Mako, что решает эту проблему. Например, этот пример шаблона будет правильно ссылаться на URL-адрес /link
, несмотря ни на что:
<%!
import cherrypy
%>
<a href="${cherrypy.url('/link')}">Click here!</a>
Это хорошо, но немного громоздко, и кажется странным import cherrypy
в моих шаблонах. Это правильный способ сделать это? Есть ли способ лучше? Было бы неплохо, если бы это было автоматически, поэтому мне не нужно помнить, что нужно оборачивать URL-адреса самостоятельно.
JavaScript
Я обслуживаю статические файлы .js, используя опцию CherryPy tools.staticdir
. Это работает нормально, но я делаю пару вызовов AJAX, и, как и статические ресурсы в моих шаблонах Mako, URL-адреса относятся к корневому каталогу моего приложения. Например, если CherryPy предоставляет URL-адрес /api/something
, и я хочу получить доступ к нему из JavaScript, как я могу написать свой JS, чтобы он по-прежнему был доступен независимо от того, где смонтировано мое приложение CherryPy?
Моя первая мысль заключалась в том, что я мог бы добавить какой-то скрытый элемент HTML или комментарий к моим шаблонам, который содержит значение cherrypy.url()
, вызываемое без аргументов, что приведет к корневому URL-адресу моего приложения, и что я мог бы пройти через DOM, захватить это значение и добавьте его к любому URL-адресу, который я хотел, прежде чем пытаться сделать HTTP-запрос. Положительным моментом является то, что это было бы довольно прозрачно в JavaScript; Недостатком является то, что было бы легко забыть включить волшебный скрытый элемент HTML, поскольку я добавляю в приложение все больше и больше шаблонов. Я полагаю, что мог бы решить эту проблему, сделав все шаблоны зависимыми от корневого шаблона, но это все еще кажется хаком.
Моя вторая мысль заключалась в том, чтобы превратить мои файлы JavaScript в шаблоны Mako, не использовать tools.staticdir
для их обслуживания и использовать тот же метод cherrypy.url()
, который я использую в своих существующих HTML-шаблонах Mako. Это привлекает согласованностью и не требует волшебного HTML-элемента в моих существующих шаблонах, но это означает, что файлы должны пройти через весь процесс рендеринга шаблона, прежде чем их можно будет обслуживать с теоретической потерей некоторой скорости, а также чувствует себя как-то неправильно.
Есть ли лучший вариант?
Другие проблемы
Хотя в настоящее время у меня нет этой проблемы, я полагаю, что в будущем я, возможно, захочу использовать URL-адреса, относящиеся к приложению, и в моих статических файлах CSS.
Проблема с запахом кода?
Я провел некоторое время в Google, SO и в документации CherryPy, пытаясь найти решение этой проблемы, но ничего не нашел. Является ли это признаком того, что я делаю что-то странное и что существует некий шаблон или передовая практика, позволяющая избежать этой проблемы, которой я просто не следую?