2011-12-05 5 views
7

어쩌면 나는 바보 일 수도 있지만 Clojure에서 선택적인 후행 슬래시와 일치하는 것을 설정할 수는 없습니다.후행 슬래시를 일치시키는 Compojure 정규식

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의 옵션 슬래시와 일치시키는 데 사용할 수있는 정규식은 무엇입니까?

답변

5

route-matches에 대한 첫 번째 인수가 정규식 아니므로 clout 예상 경로 문자열하지만, ​​키워드와 * 와일드 카드를 포함 할 수있는 문자열입니다.

clout은 원래 슬래시를 무시하는 정의 경로를 기본적으로 지원하지 않는다고 생각합니다. 후미 슬래시를 제거하는 미들웨어 기능으로 문제를 해결할 수 있습니다. 다음 함수는 이전 버전의 compojure 소스 코드 (큰 리펙토링 이전)에서 가져온 것이므로 새로운 장소로 이동했는지 알 수 없었습니다. 이 기능을 소개 한 original commit입니다.

(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)) 
+0

아, 미들웨어를 피하기 위해 기대했다. 그것이 유일한 방법이라면, OK. –

1

여기에 종속되지와 미들웨어의 압축 된 버전입니다 :

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

버그 수정 편집은 환영합니다. 더 압축 솔루션을 찾는 사람들을 위해

0

:

(defn- with-ignore-trailing-slash [handler] 
    (fn [request] 
    (let [uri (request :uri) 
      clean-uri (str/replace uri #"^(.+?)/+$" "$1")] 
     (handler (assoc request :uri clean-uri))))) 
관련 문제