Слэш в конце адреса

Подскажите кто знает:
Как сделать, чтобы в конце адреса всегда проставлялся слеш?
Сейчас ситуация такая:
site.ru — всегда без слеша на конце (пусть так и будет)
site.ru/catalog/ — ведет себя непонятно, на части страниц слэш подставляется, на части страниц доступно и со слэшем и без.
site.ru/catalog/podcatalog — доступен и со слешем и без него (а надо только со слешем)
site.ru/page.html — всегда без слэша (так и должно быть)
Я так понимаю настаивать надо nginx. Сервер настраивал по этой инструкции. От себя ничего не писал, не настраивал.
Кстати у Василия тоже примерно такая ситуация:
http://bezumkin.ru/index — всегда без слэша
http://bezumkin.ru/sections/ — и так и так доступно.
Evgeny Epifanov
26 декабря 2013, 17:58
modx.pro
12
21 930
0

Комментарии: 44

Василий Наумкин
27 декабря 2013, 08:14
0
Валисия это мало заботит, но ты можешь написать свой плагин, который при загрзке веб-страницы будет проверять её свойста, и запрошенный адрес. Если нет слеша — отправлять на него.

Хотя, в настройках MODX вроде есть strict_urls — они должны делать тоже самое, проверь.
    Николай
    27 декабря 2013, 13:21
    0
    strict_urls будут добавлять\не добалять слешы к адресу, но страницы будут доступны и так и так. Чтобы жестко указать надо делать 301 редирект в nginx. например
    location ~ .+/$ {
    rewrite (.+)/$ $1 permanent;
    }

    будет убирать слеш
      Evgeny Epifanov
      27 декабря 2013, 13:33
      0
      Спасибо за решение, но все же хочется, чтобы слэш в конце был. Есть такой вариант?
        Николай
        27 декабря 2013, 13:46
        0
        ну так слеш переставить то))
        location ~ .+/$ {
        rewrite (.+)$ $1/ permanent;
        }
        или так
        rewrite ^(.+[^/])$ $1/ permanent;
          Evgeny Epifanov
          27 декабря 2013, 19:26
          0
          Первый вариант — всегда добавляет в конец 2 слэша.
          Второй — периодически выдает 404 Not Found
          Оставлю
          location ~ .+/$ {
          rewrite (.+)/$ $1 permanent;
          }
          Так работает.
          Спасибо большое.
            Evgeny Epifanov
            27 декабря 2013, 19:38
            0
            Ага, не тут-то было, на сайте все нормально, а в админке:
            Firefox определил, что сервер перенаправляет запрос на этот адрес таким образом, что он никогда не завершится.
              Николай
              27 декабря 2013, 20:42
              0
              Попробуй так
              location ^~ /manager {
              	location ~* \.php$ {
              		include             fastcgi_params;
              		fastcgi_param       SCRIPT_FILENAME $document_root$fastcgi_script_name;
              		fastcgi_pass        backend-?????????;
              	}
              }
              
              location ~ .+/$ {
              rewrite (.+)/$ $1 permanent;
              }
                Evgeny Epifanov
                29 декабря 2013, 00:28
                0
                один фиг не работает
                  Chero
                  29 декабря 2013, 01:26
                  0
                  А настройки в системных параметрах core container_suffix "/" у вас стоит?
    Алексей Карташов
    29 декабря 2013, 23:58
    1
    0
    location / {
    	try_files			$uri $uri/ @rewrite;
    }
    location @rewrite {
    	# добавить слэш в конце
    	rewrite			(.*[^/])$ $scheme://$host$1/ permanent;
    	# удалить слэш в конце
    	#rewrite		(.*)/$ $scheme://$host$1 permanent;
    	rewrite			^/(.*)$ /index.php?q=$1 last;
    }
    Только имейте в виду, что в самом modx настройка для html в «Типах файлов» должна быть пустой. Иначе, если у вас добавляется, к примеру, ".html" к адресам страниц, то nginx исправит его на ".html/", а вы получите 404. Так что аккуратнее.
      Evgeny Epifanov
      05 мая 2014, 12:04
      0
      Оживлю тему.
      В общем условия такие:
      если:
      — адрес не содержит «sitename.ru/*.*» (т.е. в конце адреса *.html или *.jpg или еще какое-то расширение)
      и
      — в конце адреса нет слеша
      и
      — адрес не содержит «sitename.ru/manager*»
      и
      — это не главная страница (sitename.ru)
      то добавлять в конец адреса слеш.

      Прочитал уже про регулярные выражения. Уже представляю как прописать эти условия по отдельности, но не знаю как применить эти условия (конкретно отрицания) в nginx и прописать все это в одном условии.
      Кто силен в этом, помогите пожалуйста.
        Василий Наумкин
        06 мая 2014, 07:32
        0
        Можно это сделать и без nginx — плагином на OnHandleRequest.
          Evgeny Epifanov
          07 мая 2014, 00:30
          0
          Василий, спасибо за ответ.
          В общем, вот что я наваял:
          $url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];//Узнаем текущий URL
          $last = strlen($url) - 1;//Узнаем позицию последнего символа URL'a
          $slash = $url{$last};//Узнаем последний символ URL'a
          $id = $modx->getObject('modResource',$modx->resource->get('id'));//Узнаем ID ресурса
          $cat = $id->get('isofolder');//Узнаем тип ресурса (каталог или документ)
          if ($cat == '1' && $slash != '/'){//Если это каталог и в конце URL'a нет слэша,
              header("HTTP/1.1 301 Moved Permanently");//то вставляем эти заголовки.
              header("Location: $url/");
              exit();
          }
          Но получаю ошибку 500. Что не так делаю?
          И еще вопрос: админка при таком условии обрабатываться не должна?
          P.S. Над кодом прошу не смеяться
            Василий Наумкин
            07 мая 2014, 06:42
            1
            0
            Если ты хочешь работать с ресурсом, то OnHandleRequest — слишком раннее событие, он там еще не загружен. Это событие срабатывает в самом начале обработки запроса, именно поэтому его можно использовать как php-замену правилам nginx.

            А плагин для редиректа на канонический uri документа-контейнера выглядит так:
            <?php
            if ($modx->event->name == 'OnLoadWebDocument') {
            	$uri = $_SERVER['REQUEST_URI'];
            	if ($modx->resource->isfolder && substr($uri, -1) != '/') {
            		$modx->sendRedirect($modx->makeUrl($modx->resource->id));
            	}
            }
              Evgeny Epifanov
              07 мая 2014, 18:21
              1
              +1
              Василий, спасибо тебе большое!
              От себя добавлю: sendRedirect — по умолчанию делает 302 редирект, для 301
              $modx->sendRedirect($modx->makeUrl($modx->resource->id),array('responseCode' => 'HTTP/1.1 301 Moved Permanently'));
                Evgeny Epifanov
                13 мая 2014, 20:01
                0
                Василий, снова я тебя потревожу.
                Плагин работает отлично! Столкнулся с такой ситуацией: в категории при пагинации на другую страницу (напр.: site.ru/category/?page=2) при переходе она нормально отображается, а если этот адрес отрыть в новой вкладке или браузере, то плагин редиректит на site.ru/category/ что несколько неудобно, если требуется отправить такую ссылку по почте, да и страницы эти из поисков повылетают со временем.
                Помоги решить, пожалуйста.
                  Илья Уткин
                  13 мая 2014, 20:12
                  0
                  if ($modx->resource->isfolder && substr($uri, -1) != '/' && !$_GET['page']) {
                  Уж это-то элементарно…
                    Evgeny Epifanov
                    13 мая 2014, 20:19
                    0
                    Большое спасибо!
                    Уж это-то элементарно…
                    не сомневаюсь… Начинал я изучать PHP, но что-то как-то сложно.
                    Александр
                    14 мая 2014, 00:23
                    0
                    А если пагинация сделана через AJAX и перезагрузки страницы не происходит, как в таком случае быть? Подскажите?
                  Evgeny Epifanov
                  14 мая 2014, 21:28
                  0
                  Ну, вот. Снова…
                  С page разобрались, а вот при фильтрации через mFilter то же самое, что и тут
                    Evgeny Epifanov
                    22 сентября 2014, 17:28
                    2
                    +2
                    Если кому-то интересно, решил все кардинально:
                    if ($modx->event->name == 'OnLoadWebDocument') {
                    	$uri = $_SERVER['REQUEST_URI'];
                    	if ($modx->resource->isfolder && substr($uri, -1) != '/' && !strpos($uri, '?')) {
                    		$modx->sendRedirect($modx->makeUrl($modx->resource->id),array('responseCode' => 'HTTP/1.1 301 Moved Permanently'));
                    	}
                    }
                      Василий Наумкин
                      22 сентября 2014, 17:46
                      +1
                      Так и надо!
                        Сергей
                        30 сентября 2014, 01:28
                        0
                        а проблему с index.php/хотьчто/ решал кто нибудь?
                          Evgeny Epifanov
                          30 сентября 2014, 09:48
                          0
                          Вот до этого и внимания не обращал.
                          Лично у меня с «index.php/хотьчто/» все нормально 404 ошибка. А вот «site.ru/index.php» работает. Прописал в nginx (по аналогии с index.html):
                          location /index.php {
                                          rewrite                 / / permanent;
                                  }
                          результата не дало.
                          Также есть проблемы с:
                          site.ru/catalogue/index.html(.php) -> редирект на site.ru// (именно два слеша на конце), а должно быть на site.ru/catalugue/
                          если на главной или в категории в конце поставить сколько угодно слешей, то страница все равно отдаст код 200
                            Сергей
                            30 сентября 2014, 10:33
                            0
                            про много слэшей даже яндекс грешен www.yandex.ru/////
                            я сделал 404 на /catalog/index.php, а когда сайт.ru/index.php 301 на /.
                            меня больше заботит index.php/хотьчто/, т.к. сайт был раньше на Джумле с таким ссылками, сейчас на revo, а ссылки эти кривые остались в индексе и отдают 200 код. Сейчас еще два других сайта проиндексируются с index.php/хотьчто/ так как на них проверил этот баг ))))
                              Evgeny Epifanov
                              30 сентября 2014, 10:41
                              0
                              Вообще, если это перенос, то по хорошему нужно всем старым страницам нужно прописать редиректы на новые страницы, тогда Redirector в помощь. А так, если 404 станица настроена, MODx сам на нее должен редиректить. В том же Redirector'e можно настроить редирект на 404. Ну и как вариант в robots.txt поставить запрет на индексацию.
                                Сергей
                                30 сентября 2014, 12:35
                                0
                                да походу я заработался ))) RewriteRule ^index.php/(.*)$ / [R=permanent,L]
                        Mihan
                        30 сентября 2014, 13:15
                        0
                        Это вставлять в index.php после вызова MODX_API?
                          Сергей Шлоков
                          03 октября 2014, 13:49
                          0
                          Нужно создать плагин и повесить его на событие «OnLoadWebDocument».
                      but1head
                      03 октября 2014, 10:00
                      0
                      Как добавить слеш в конце адреса к обычным ресурсам? К примеру используя плагин от Вac слеш есть у всех ресурсов-контейнеров, а у тех, что без «дочерних» его нету. При выставлении галки «контейнер» — появляется. Но нужно, что бы у всех урлов был слеш (кроме главной).
                        Сергей Шлоков
                        03 октября 2014, 13:38
                        0
                        Нет ничего проще. В системных настройках заменить суффикс для ресурсов «html» на "/".
                          but1head
                          03 октября 2014, 13:42
                          0
                          не помогает. ресурс доступен со слешем и без, если оставить настройку пустой — сам убирает.
                            Сергей Шлоков
                            03 октября 2014, 13:57
                            +1
                            Смысл твоего вопроса был в чем — как добавить слеш в конце адреса ресурса. Я тебе ответил. Как убрать дубль — это другой вопрос. Обсуждалось сто раз. Читай
                Александр Толстенко
                03 ноября 2016, 12:17
                0
                а если в .htaccess то что надо прописать?
                Писал так:
                RewriteCond %{REQUEST_FILENAME} !-f
                RewriteCond %{REQUEST_URI} !(.*)/$
                RewriteRule ^(.*)$ /$1/ [R=301,L]
                и так:
                RewriteCond %{REQUEST_FILENAME} !-f
                RewriteCond %{REQUEST_URI} !(.*)/$
                RewriteRule ^(.*[^/])$ $1/ [L,R=301]
                результата нет. Что делаю не так?
                  Александр Толстенко
                  03 ноября 2016, 12:36
                  0
                  еще пробовал вот так:
                  # Remove trailing slash
                  RewriteRule ^(manager)/*$ — [L] # exclude manager folder
                  RewriteCond %{REQUEST_URI} (.*)/
                  RewriteRule ^(.*)/$ example.com/$1 [R=301,L]
                  результата ноль. Кто сталкивался с такой проблемой и решил ее?
                    Николай
                    01 апреля 2017, 14:48
                    4
                    +1
                    Постарался чуть более универсальное решение написать для тех случаев, когда обратный слеш нужен не только для папок, но и для документов.

                    Те. сайт/категория/товар/
                    <?php
                    if ($modx->context->key == 'mgr') {return;}
                    $uri=$_SERVER['REQUEST_URI'];
                    if (substr($uri, -1) != '/' && $uri != '/' && !strpos($uri, '?')&& !strpos($uri, '.')) {
                    	$url = $modx->getOption('site_url');
                    	if(substr($url, -1)=='/'){
                    		$url=substr($url, 0, -1);
                    	}
                    	$url .= $uri.'/';
                    	$modx->sendRedirect($url,array('responseCode' => 'HTTP/1.1 301 Moved Permanently'));
                    }
                      Тим
                      18 июля 2017, 17:19
                      0
                      Простите я новичок в модкс. Не подскажете куда вот это чудо надо вписать?
                        Николай
                        19 июля 2017, 20:17
                        0
                        Нужно создать плагин и в него поместить этот код. В настройках указать событие OnHandleRequest
                        Eugene
                        28 сентября 2018, 13:59
                        0
                        Николай, подскажите, а можно ли как то добавить условие, чтоб у конкретных страниц редирект был на без /, а остальные на с /
                          Zulya
                          26 ноября 2018, 16:35
                          1
                          0
                          Здравствуйте!
                          Возможно ли в этом коде также прописать редирект с .html в конце /, то есть, убрать точку с html и вместо добавить слеш?
                          У меня на сайте дочерние ресурсы были с .html в конце url. Но я их сделала контейнерами и теперь они стали со слеш. А автоматического редиректа не происходит. Пожалуйста, посоветуйте, как исправить это? Спасибо!
                          Вася
                          28 сентября 2018, 18:13
                          1
                          0
                          Вот пример слеша для контейнеров

                          if ($modx->event->name == 'OnWebPagePrerender')
                          {
                              if ($modx->resource->get('isfolder') == 1)
                              {
                                  $rest = substr($_SERVER['REQUEST_URI'], -1);
                                  if ($rest != '/')
                                  {
                                      header("Location: " . $_SERVER['REQUEST_URI'] . "/");
                                      exit;
                                  }
                              }
                          }
                            Юрий
                            22 сентября 2019, 02:08
                            0
                            Настраил seoFilter, при переходе на сгенерированный урл — происходит редирект на оснвной урл, на котором работают фильтры. А если отметить чекбокс в фильтре — то урл выстраивается как надо. Есть возможность в плагине Василия это както пофиксить?
                              Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                              44