Compojure регулярное выражение для соответствия конечной косой черты
Может быть, я просто идиот, но я не могу установить совпадение для дополнительной косой черты в Clojure.
lein repl
REPL started; server listening on localhost port 47383
user=> (use 'ring.mock.request 'clout.core)
nil
user=> (route-matches "/article/" (request :get "/article/"))
{}
user=> (route-matches "/article/?" (request :get "/article"))
nil
user=> (route-matches "/article/?" (request :get "/article/"))
nil
user=> (route-matches #"/article/?" (request :get "/article/"))
java.lang.IllegalArgumentException: No implementation of method: :route-matches of protocol: #'clout.core/Route found for class: java.util.regex.Pattern (NO_SOURCE_FILE:0)
Какое регулярное выражение я могу использовать, чтобы сопоставить необязательный конечный слеш в Compojure?
3 ответа
Строка пути, ожидаемая clout
в качестве первого аргумента route-matches
это не регулярное выражение, а строка, которая может содержать ключевые слова и *
подстановочные.
я верю clout
изначально не поддерживает определение маршрутов, которые игнорируют косую черту. Вы можете решить проблему с помощью функции промежуточного программного обеспечения, которая удаляет завершающие косые черты. Следующие функции были взяты из старой версии compojure
Исходный код (до большого рефакторинга), я не мог узнать, переехали ли они на новое место. Вот оригинальный коммит, который ввел эти функции.
(defn with-uri-rewrite
"Rewrites a request uri with the result of calling f with the
request's original uri. If f returns nil the handler is not called."
[handler f]
(fn [request]
(let [uri (:uri request)
rewrite (f uri)]
(if rewrite
(handler (assoc request :uri rewrite))
nil))))
(defn- uri-snip-slash
"Removes a trailing slash from all uris except \"/\"."
[uri]
(if (and (not (= "/" uri))
(.endsWith uri "/"))
(chop uri)
uri))
(defn ignore-trailing-slash
"Makes routes match regardless of whether or not a uri ends in a slash."
[handler]
(with-uri-rewrite handler uri-snip-slash))
Вот сжатая версия промежуточного программного обеспечения без зависимостей:
(defn with-ignore-trailing-slash [handler] (fn [request]
(let [uri (request :uri)
clean-uri (if (and (not= "/" uri) (.endsWith uri "/"))
(subs uri 0 (- (count uri) 1))
uri)]
(handler (assoc request :uri clean-uri)))))
Исправление ошибок исправления приветствуются.
Для тех, кто ищет еще более сжатое решение:)
(defn- with-ignore-trailing-slash [handler]
(fn [request]
(let [uri (request :uri)
clean-uri (str/replace uri #"^(.+?)/+$" "$1")]
(handler (assoc request :uri clean-uri)))))