Pracuje pod Ruby 1.8.7, Rails 3.0.3, MySQL 5.1.49.
Obecnie mam mniej więcej taki kod HTML:
<a class="first selected" href="#">Strona główna</a>
<a href="#">Regulamin</a>
<a href="#">FAQ</a>
<a href="#">Kontakt</a>
<a href="#">Do pobrania</a>
Chcę by kontroler przybierał taką postać:
/article/ID/tytuł
Tytuł nie powinien być brany pod uwagę, tak go daje by ładniej linki wyglądały.
Wyjdzie coś takiego:
<a class="first selected" href="#">Strona główna</a>
<a href="/article/1/regulamin">Regulamin</a>
<a href="/article/2/faq">FAQ</a>
<a href="/article/3/kontakt">Kontakt</a>
<a href="/article/4/do-pobrania">Do pobrania</a>
Da się coś takiego zrobić?
Z góry dziękuje za odpowiedź.
(nie weryfikowałem, ale powinno działać). Dostajesz id i title w params, oczywiście title możesz zignorować.
Wszystko pod warunkiem, że kontroler nazywa się “ArticlesController” i posiada akcję “show”.
[quote=Matthias]<a class="first selected" href="#">Strona główna</a>
<a href="/article/1/regulamin">Regulamin</a>
<a href="/article/2/faq">FAQ</a>
<a href="/article/3/kontakt">Kontakt</a>
<a href="/article/4/do-pobrania">Do pobrania</a>
Da się coś takiego zrobić?
Z góry dziękuje za odpowiedź.[/quote]
Jeśli to są strony “statyczne”, zrób tak w routing.rb:
get "regulamin" => "pages#regulamin", :as => :regulamin
get "faq" => "pages#faq", :as => :faq
get "kontakt" => "pages#kontakt", :as => :kontakt
get "do-pobrania" => "pages#do_pobrania", :as => :do_pobrania
Akcji w kontrolerze w ogóle nie musisz definiować (lub mogą być puste).
Jeśli natomiast stoi za tym model, najlepsze rozwiązanie dał Świstak - gem stringex w czysty i kompletny sposób wspiera przyjazne URL-e.
jeśli są to strony statyczne, to w public/ tworzy się stronę .html i odwołuje przez strona.pl/foo.html. A gdy mamy naprawdę mocno obciążony serwis, to wydziela się takie strony gdzieś “wysoko”, żeby taki request wogóle nie dotykał stosu railsowego.
Jeśli plik leży w public to żądanie nie dotyka w ogóle railsów (zakładam, że serwer jest poprawnie skonfigurowany). Poza tym po co tworzyć statyczne pliki w public/ jak można zrobić normalne widoki i dać im keszowanie do statycznych plików? Po co? Jak Ci przyjdzie zmienić coś w layoucie to zmienisz w 1 pliku, usuniesz cache i działa :).
[quote=apohllo]W 3 w nowym routingu można to zrobić tak:
match 'article/:id/:title' => "articles#show"
(nie weryfikowałem, ale powinno działać). Dostajesz id i title w params, oczywiście title możesz zignorować.
Wszystko pod warunkiem, że kontroler nazywa się “ArticlesController” i posiada akcję “show”.[/quote]
Działa. Co prawda jest wymagany title ale mimo wszystko bangla.
Jak będę miał czas to wypróbuje pozostałe metody.
Edycja:
match 'articles/:id/:title' => "articles#show"
match 'articles/:id/' => "articles#show" I po problemie.
[quote=Matthias][quote=apohllo]W 3 w nowym routingu można to zrobić tak:
match 'article/:id/:title' => "articles#show"
(nie weryfikowałem, ale powinno działać). Dostajesz id i title w params, oczywiście title możesz zignorować.
Wszystko pod warunkiem, że kontroler nazywa się “ArticlesController” i posiada akcję “show”.[/quote]
Działa. Co prawda jest wymagany title ale mimo wszystko bangla.[/quote]
Title powinien być wymagany, bo inaczej będziesz miał duplicated content w google.
Jeśli jednak chciałbyś zrobić go opcjonalnym, wystarczy ująć w nawiasy: ‘article/:id(/:title)’.
Nie używaj match. Te “makro” akceptuje każdą metodę HTTP. Tymczasem akcja kontrolera powinna odpowiadać na dokładnie jedną metodę HTTP. Zamień “match” na “get” i ciesz się czystością publicznego interfejsu aplikacji.
To czy title jest wymagany czy nie nie ma żadnego wpływu na SEO. Przy wymaganym tytule możesz mieć równie dobrze /articles/1/hello i /articles/1/world i jeśli pobierasz artykuł po ID to i tak masz powieloną treść.
Lepszym rozwiązaniem tego problemu jest użycie rel=“canonical” (lub ew. przekierowań).
Ma duży wpływ: jeśli na jednej stronie zalinkują /articles/1, a na drugiej /articles/1/dupa, to te ścieżki przez gugla będą traktowane jako dwa różne URLe (czyli o osobnych pagerankach)
Wygeneruje się ładny url np. “/articles/2-pytania-i-odpowiedzi”[/code]
Nie trzeba trzeba do tego gemów, parameterize zajmie się i znakami diaktrycznymi i białymi.
Można skorzystać z tego, że jeśli w kontrolerze mamy coś w stylu @article = Article.find(params[:id]) to :id może przyjąć wartość “2”, może też przyjąć “2-pytania-i-odpowiedzi”, efekt będzie ten sam. Wtedy można zrezygnować z dodatkowego ukośnika, który jest w tym przypadku mylący, bo sugeruje zejście na poziom niżej.