[Nice URLS] Tytuł w URL-u - pl znaki i spacje

Witam.
W tematyce Ruby i ROR jestem dość nowy i mam pewien problem
Otóż chcę sobie zrobić linki w postaci:

strona.pl/news/show/5/to-jest-przykladowy-post.html

Nie ma problemów z jego wykonaniem, poza tą ostatnią sprawą - tytułem. Moje pytanie jest następujące: jaka metoda w ruby/jaki helper czyści string z niepotrzebnych znaków/ bądź przygotowuje URL.

Pozdrawiam,
Matix.

Kiedyś napisałem sobie coś takiego:

[code]def make_url(p_str)
str = String.new(p_str)
str.strip!

s =  ['ą', 'ć', 'ę', 'ł', 'ń', 'ó', 'ś', 'ż', 'ź',
             'Ą', 'Ć', 'Ę', 'Ł', 'Ń', 'Ó', 'Ś', 'Ż', 'Ź',
             'é', 'à', ' - ', 'À', 'Á', 'Ã', 'Ä', 'Å',
             'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î',
             'Ï', 'Đ', 'Ñ', 'Ô', 'Õ', 'Ö', 'Ù', 'Û', 'Ý',
             'ß', 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç',
             'è', 'é', 'ê', 'ë', 'ì', 'í', 'í', 'î', 'ï',
             'ñ', 'ò', 'ô', 'õ', 'ö', 'ù', 'ú', 'û', 'ü',
             'ý', 'ÿ', '€', '$', 'Š', 'š', 'ž', 'Œ', 'œ',
             'Ÿ', '§', '@' ]
r = ['a', 'c', 'e', 'l', 'n', 'o', 's', 'z', 'z',
             'a', 'c', 'e', 'l', 'n', 'o', 's', 'z', 'z',
             'e', 'a', '-', 'a', 'a', 'a', 'a', 'a',
             'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i',
             'i', 'd', 'n', 'o', 'o', 'o', 'u', 'u', 'y',
             'b', 'a', 'a', 'a', 'a', 'a', 'a', 'ae', 'c',
             'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', 'i',
             'n', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u',
             'y', 'y', 'e', 's', 's', 's', 'z', 'oe', 'oe',
             'y', 'p', 'at' ]
s.each_index {|i| str.gsub!(s[i], r[i])}
str.downcase!
str.gsub!(Regexp.new('\ +'), '-')
str.gsub!(Regexp.new('[^A-z0-9\-]'), '')
str.gsub!(Regexp.new('\-+', '-'), '-')
str

end[/code]
Konwertuje do URL w postaci takiej, jak piszesz (nie dodaje .html). Nie jest pewnie optymalna, bo to pochodzi z mojej pierwszej aplikacji w RoR, ale działa i sprytnie zamienia polskie literki i niektóre inne akcenty na ich odpowiedniki niekacentowane. Sam jestem ciekaw, czy ktoś dysponuje inną implementacją.

3 uwagi:

  1. czy faktycznie chcesz usuwać polskie znaki z tytułu w URLu? Co prawda obecnie przeglądarki wyświetlają je jako krzaczki, ale biorąc pod uwagę fakt, że znaki diakrytyczne mogą pojawiać się w nazwach domen, to prawdopodobnie w niedługiej przyszłości będą one wyświetlane poprawnie. Jaki jest z tego zysk? SEO - np. Google wyżej wyświetli stronę, która ma w adresie xyz.abc.com/10-kraków niż xyz.abc.com/10-krakow jeśli użytkownik wprowadzi zapytanie o Kraków. Co ciekawe jak wprowadzi Krakow, to i tak będzie wyszukiwany Kraków!

  2. istnieje plugin acts_as_sluggable, który dodaje do url’a dowolnie wybrane pola z modelu. Działa o tyle fajnie, że nie musisz w ogóle modyfikować routerów - zawsze brany jest pod uwagę wyłącznie identyfikator (np. 10 w powyższym przykładzie), a reszta jest ignorowana. Pozwala to na dodanie tej funkcjonalności na stronach, które już znajdują się w indeksie wyszukiwarek.

  3. w zaproponowanym kodzie można było skorzystać z metody String#tr - nie trzeba by wtedy tworzyć osobnych
    tablic, tylko dwa napisy. Nie jestem jednak pewien czy zadziałałoby to dla łańcuchów zakodowanych UTF8. Można też było dołączyć tę metodę do klasy string, ale to już szczegół.

Słabo znam się na SEO, na pewno masz rację co do tego, co piszesz. Nie rozważałem tego w ten sposób, wg Google trends różnica faktycznie jest dość spora - http://www.google.com/trends?q=kraków%2C+krakow. Z tym, że jak to zwykle bywa z Google, “ó czy o” to chyba tylko jeden z dziesiątków aspektów, bo w praktyce moja strona z krakow w URL ma taką samą pozycje na kraków i krakow, a krakow wyglada nieco czytelniej niż ciąg szlaczków.

Co do implementacji, to Rubym jak w Perlu - wszystko można zapewne napisać 5x krócej i nie spędza mi to snu z powiek, bo czytelność też jest dla mnie istotna. W przypadku tej implementacji na pewno można by użyć %w do tablicy, czy zamienić 2 regexpy na 1 i połączyć | itp. itd. Jednak chyba nie mam aż tak dużo czasu, żeby przepisywać soft sprzed roku jeszcze raz z okazji świąt :-). Niestety niektóre znaki zmieniają się na dwa, więc string chyba nie miałby sensu.

Co do “lepszej” implementacji, to w tym wypadku skrócenie właśnie poprawiłoby czytelność (można by napisać dwa łańcuchy jeden nad drugim i od razu byłoby widać odpowiednie mapowanie)… gdyby nie fakt, który przeoczyłem, czyli zamiany 1 litery na 2.
A co do krótszego kodu to zgadzam się w 100% - nie ma sensu tego robić, jeśli nie poprawia to czytelności. Wspomniałem o metodzie String#tr bo jest ona zaczerpnięta z unixowego polecenia o tej samej nazwie - zrobiłem to w celach czysto edukacyjnych :slight_smile:

http://blog.drogomir.com/articles/2008/01/12/przyjazne-adresy-w-ruby-on-rails - napisałem tutaj artykuł o tym jak to wszystko zrobić w miarę bezboleśnie. Jest link do artykułu mighty Obiego, w którym podaje on implementację zamiany znaków diakrytycznych. A tr rzeczywiście nie obsługuje UTF-8.

Pozdro666

Sam mechanizm, który opisałeś na stronie (bez zamiany znaków diakrytycznych) jest właśnie implementowany przez wspomniany plugin acts_as_sluggable.

Tak, wiem. Ale ja będę musiał jeszcze zrobić parę modyfikacji tej metody na własne potrzeby. Dlatego obczaiłem jak to działa. Opisałem, bo może komuś się przyda. :slight_smile:

Dzięki drogus, myślę, że proponowana przez ciebie metoda jest optymalna i z acts_as_sluggable można dać sobie spokój (http://tore.darell.no/pages/acts_as_sluggable), trzeba i tak go/ją podrasować pod znaki specjalne, które nawiasem mówiąc z tego co widzę nie będą wyświetlane w FireFox3, więc esteci muszą wziąć je pod nóż :slight_smile:

ps. co do Google, to aspekt ZA ‘pełnymi urlami’, który zauważam, to większa precyzyjność jeżeli chodzi o kanały AdSense