понедельник, 27 сентября 2010 г.

TYPO3 и SEO (часть вторая - tt_news)

В предыдущей статье, а точнее в первой части темы TYPO3 и SEO, я рассказывал о том, как в Typo3 с помощью дополнительных плагинов и TypoScript можно формировать Title и Description обычных страниц системы - page. Но сайт на Typo3 может иметь и другие страницы...

Tt_news - одно из наиболее популярных расширений, применяемых с Typo3. Данный плагин для просмотра всего списка новостей использует одну единственную страницу - страницу детального просмотра новости. Для единообразия и более успешной раскрутки сайта, данная страница должна иметь тот же формат Title, что и все остальные страницы.

Я покажу как это можно сделать.

Предположим, что мы имеем следующие страницы на сайте:




Причем, уникальные идентификаторы страниц (uid) имеем следующие:
Новости - 12
Новости сайта - 37 (страница единичного просмотра)
Новости и статьи - 4 (Sysfolder со списком новостей)

Typo3 шаблон для страницы Новости и Новости сайта:
plugin.tt_news.code >
# Не индексируем страницу со списком новостей
config.index_enable = 0

plugin.tt_news {
code = LIST
}
[globalVar = TSFE:id = 70]
# На данной странице показываем только архивные новости
plugin.tt_news.archive = 1
[else]
plugin.tt_news.archive = -1
[global]

[globalVar = GP:tx_ttnews|tt_news > 0]
# Страница единичной новости
plugin.tt_news.code = SINGLE
# Страницу единичной новости - индексируем!
config.index_enable = 1
# Для единичной новости или статьи создаем мета-теги по нашим правилам
config.noPageTitle = 2

# Для description страницы используем subheader - подзаголовок новости
page.meta.description >
page.meta.description.data = register:newsSubheader

# Запросом находим title - заголовок новости
lib.meta_news=CONTENT
lib.meta_news.table = tt_news
lib.meta_news.select {
pidInList = 4
andWhere.data = GP:tx_ttnews|tt_news
andWhere.intval = 1
andWhere.wrap = uid=|
}

# Это будет перенос на новую строку (см. далее)
lib.meta_news.renderObj = COA
lib.meta_news.renderObj.5 = TEXT
lib.meta_news.renderObj.5.value (

)

lib.meta_news.renderObj.10 = TEXT
lib.meta_news.renderObj.10 {
field = title
wrap = <title>| : Имя сайта</title>
}
lib.meta_news.renderObj.10.append < lib.meta_news.renderObj.5

# Ручная генерация мета-тега - description
# (если кому-то интересно - можно разкомментировать, но убрать page.meta.description выше)
#lib.meta_news.renderObj.20 = TEXT
#lib.meta_news.renderObj.20 {
# field = short
# wrap = <meta name="description" content="|" />
#}
#lib.meta_news.renderObj.20.append < lib.meta_news.renderObj.5

# Записываем в заголовок мета данные
page.headerData.776 >
page.headerData.776 < lib.meta_news

[global]

# Остальные настройки новостей
plugin.tt_news.stdWrap.wrap =
|

plugin.tt_news.templateFile = fileadmin/templates/tt_news_v3_template.html
# Указываем id папки с новостями
plugin.tt_news.pid_list = 4
# Указываем страницу для детального просмотра
plugin.tt_news.singlePid = 37
# Количество новостей в списке
plugin.tt_news.limit = 6
# Задаем формат даты
plugin.tt_news.displayList.date_stdWrap.strftime = %d.%m.%Y
# Если у новости нет подзаголовка, то в режиме списка новостей отображаем первые 250 символов её "тела"
plugin.tt_news.displayList.subheader_stdWrap {
crop = 250 | ... | 1
ifEmpty.field = bodytext
}
lib.newsContent < plugin.tt_news
воскресенье, 18 июля 2010 г.

TYPO3 и SEO (часть первая)

Думаю, ни для кого не секрет, что базовыми элементами SEO являются: заголовок страницы (TITLE), описание страницы (META DESCRIPTION) и набор ключевых слов (META KEYWORDS).

Благодаря своему скрипту, Typo3 позволяет динамично и довольно гибко управлять данными параметрами, что делает тайповские сайты дружественными для поисковых систем.

Ну что ж, начнем, пожалуй? Но для начала установим небольшое, очень простое и очень полезное расширение - seo_basics.

Данное расширение позволяет очень эффективно просматривать и редактировать все вышеперечисленные параметры для всех страниц сайта:









Очень удобным является то, что с помощью цвета полей ввода seo_basics говорит о корректности длины полей (желтый - коротко, зеленый - норма, красный - перебор).


После редактирования полей их необходимо активировать с помощью следующего TypoScript:

page.meta.keywords.field = keywords
page.meta.description.field = description

А где же активация Title спросите Вы. Тут не все так просто! Дело в том, что заголовок страницы, как правило, является составным. В моей практике, это чаще всего - заголовок текущей страницы + разделитель + название сайта. На самом деле, правила формирования Title могут быть какими-угодно. Здесь главное помнить следующее:
1. Поисковики учитывают только 70-80 символов заголовка (Google - 70, Yandex - 80);
2. Чем ближе к началу фразы слово, тем его вес для поисковиков выше;
3. Чем короче заголовок страницы тем весомее каждое его слово;
4. Крайне желательно, чтобы на сайте не было страниц с повторяющимися Title, т.е. заголовки страниц должны быть уникальными.

Я покажу как сформировать заголовок в формате:
Заголовок страницы : Имя сайта (компании)

Имя сайта прописывается здесь:





Теперь с помощью TypoScript собираем все вместе:


# Говорим TYPO3 что title мы формируем сами
config.noPageTitle = 2

plugin.tx_seobasics_sitetitle >
plugin.tx_seobasics_sitetitle = TEXT
plugin.tx_seobasics_sitetitle {
cObject =< plugin.tx_seobasics_sitetitle.multilang
ifEmpty.data = TSFE:tmpl|sitetitle
}

plugin.tx_seobasics >
plugin.tx_seobasics = COA
plugin.tx_seobasics {
# Формируем title страницы
10 = TEXT
10.data = page:tx_seo_titletag // page:title
10.trim = 1
10.stdWrap.stdWrap.append = TEXT
10.stdWrap.stdWrap.append.cObject < plugin.tx_seobasics_sitetitle
10.stdWrap.stdWrap.append.trim = 1
10.stdWrap.stdWrap.append.required = 1
10.stdWrap.stdWrap.append.if.isTrue = {$plugin.tx_seo.titleWrapAppendSiteTitle}
10.stdWrap.stdWrap.append.noTrimWrap = | : ||
10.stdWrap.noTrimWrap = {$plugin.tx_seo.titleWrap}
10.stdWrap.insertData = 1
10.htmlSpecialChars = 1
10.wrap = <title>|</title>

# Если Вам нужен и мета-тег title раскомментируйте нижние две строки
#20 < .10
#20.wrap = <meta name="title" content="|" />

# Ниже приведен скрипт позволяющий формировать остальные SEO-теги вручную

# Building the Keywords tag
#30 = TEXT
#30 < .10
#30.data = page:keywords
#30.stdWrap.noTrimWrap = {$plugin.tx_seo.keywordsWrap}
#30.stdWrap.stdWrap >
#30.required = 1
#30.wrap = <meta name="keywords" content="|" />

# Building the Description tag
#40 = TEXT
#40 < .30
#40.data = page:description
#40.stdWrap.noTrimWrap = {$plugin.tx_seo.descriptionWrap}
#40.wrap = <meta name="description" content="|" />

# Building the date tag (last changed)
#50 = TEXT
#50 < .10
#50.data = page:SYS_LASTCHANGED // page:crdate
#50.date = Y-m-d
#50.stdWrap >
#50.wrap = <meta name="date" content="|" />
}

# Записываем наши теги с раздел head страницы сайта
page.headerData.776 = < plugin.tx_seobasics

P.S. В репозитории расширений Typo3 имеется масса СЕО-прибомбасов, в том числе и такие, которые сами генерируют набор ключевых слов для каждой страницы сайта.

 

понедельник, 28 июня 2010 г.

Продвинутое меню breadcrumb или осваиваем optionSplit

 


Примеров того, как создать простое breadcrumb-меню (навигационное меню) в сети предостаточно, но, чтобы создать более продвинутый его вариант (см. рисунок ниже) пришлось не только погуглить и читать мануалы, но и немного поработать серым веществом.




Итак, поставленная задача примерно такова:
1. Домашнюю страницу нужно отобразить изображением - домиком (это 0-й уровень меню)
2. Меню 1-го уровня (About ICH) необходимо отобразить ссылкой серого цвета
3. Меню остальных уровней - обычные ссылки
4. Текущий пункт меню должен быть крупным и жирным
5. Пункты меню должны отображаться задом наперед, как на картинке.


Эту задачу я не решил, если бы не замечательное свойство optionSplit.

Так, что же такое optionSplit и что оно нам дает?

Само название свойства говорит о том, что оно что-то разбивает на части. Так и есть, optionSplit позволяет разбить любую субстанцию на 3 части с помощью специального разделителя - |*|. Эти три части устроены так: первая, последняя и все остальное, что осталось между ними:

...first part... |*| ...middle part... |*| ...last part...

Сразу для наглядности небольшой пример,
ACT.doNotShowLink = 1 |*| 0 |*| 1
Эта конструкция сделает первый и последний элемент меню простым текстом, а все остальные ссылками.

Если пока еще ничего не понятно, то сейчас при решении нашей конкретной задачи станет яснее:
1. Организуем наше меню с помощью списков UL и LI. Создаем скрипт-заготовку:
lib.breadcrumb = HMENU
lib.breadcrumb.special = rootline
lib.breadcrumb.special.range = 0|-1
lib.breadcrumb.wrap = <ul> | </ul>
lib.breadcrumb.1 = TMENU
lib.breadcrumb.1{
noBlur = 1
NO.allWrap = <li> | </li>

ACT = 1
ACT.allWrap = <li> | </li>

CUR = 1
CUR.allWrap = <li> | </li>
CUR.doNotLinkIt = 1
}

2. Делаем первый пункт навигационного меню изображением домика (следите за изменениями ACT.allWrap).

Сначала наш список пунктов меню делим на 3 части:

ACT.allWrap = <li class="firstcrumb">|</li>|*|<li>|</li>|*|<li class="lastcrumb">|</li>

Добавляем для первого меню картинку:
ACT.allWrap = <li class="firstcrumb">|<img src="fileadmin/templates/img/home.png" alt="Home" /></li>|*|<li>|</li>|*|<li class="lastcrumb">|</li>

Делаем изображение ссылкой:
ACT.allWrap = <li class="firstcrumb">|<a href="http://www.domain.com/"><img src="fileadmin/templates/img/home.png" alt="Home" /></a></li>|*|<li>|</li>|*|<li class="lastcrumb">|</li>

Удаляем текстовую ссылку возле домика:
ACT.allWrap = <li class="firstcrumb"><a href="http://www.domain.com/"><img src="fileadmin/templates/img/home.png" alt="Home" /></a></li>|*|<li>|</li>|*|<li class="lastcrumb">|</li>
# здесь делим список всего на 2 части - первый пункт меню и все остальные
# первый пункт меню - не ссылка!
ACT.doNotShowLink = 1 |*| 0

3. Меню 1-го уровня (About ICH) необходимо отобразить ссылкой серого цвета:
Данный пункт меню является вторым по счету и находится в промежутке между первым и последним пунктом меню. Но как ему задать персональный CSS-стиль? Оказывается optionSplit имеет дополнительные возможности по разбиванию на части. Дополнительная разбивка происходит с помощью специального разделителя - ||(две палки!). Таким образом, по левую сторону от первого разделителя |*|, мы создаем индивидуальные настройки для 1-го и 2-го уровня меню:
ACT.allWrap = <li class="firstcrumb"><a href="http://www.domain.com/"><img src="fileadmin/templates/img/home.png" alt="Home" /></a></li>||<li class="secondcrumb">|</li>|*|<li>|</li>|*|<li class="lastcrumb">|</li>
# здесь делим список всего на 2 части - первый пункт меню и все остальные
# первый пункт меню не отображаем
ACT.doNotShowLink = 1 |*| 0

4. Делаем текущий пункт меню крупным и жирным текстом.
CUR = 1
CUR.doNotLinkIt = 1
CUR.allWrap = <li><strong> | </strong></li>


5. Пункты меню должны отображаться задом наперед:
Тут я схитрил и воспользовался услугами CSS, хотя не исключаю, что все можно было сделать и с помощью TS.
ul, ul li{
display:inline;
list-style:none;
}
#navmenu ul{
float:left;
}
#navmenu li{
float:right;
}

Однако, данный способ не работает в злополучном IE7. Поэтому здесь можно выполнить реверс (обратную перестановку) пунктов меню при помощи свойства - itemArrayProcFunc, которое вызывает пользовательскую функцию, написанную на PHP.

Сначала создаем файл tools.php в директории fileadmin/userfuncs/ следующего содержания:
<?php
class user_tools {

function reverseMenuItemProcFunc($I,$conf) {
return array_reverse($I);
}
}
?>

Подключаем и вызываем нашу пользовательскую функцию к скрипту:

includeLibs.myFunc = fileadmin/userfuncs/tools.php
lib.breadcrumb.1.itemArrayProcFunc = user_tools->reverseMenuItemProcFunc

Теперь можно изменить css:
#navmenu li{
float:left;
}


6. Поставим разделитель в виде наклонного слэша между нашими пунктами меню:
ACT.allWrap = <li class="firstcrumb"><span class="delim">/</span><a href="http://www.domain.com/" title="Home"><img src="fileadmin/templates/img/home.png" alt="Home" /></a></li>||<li class="secondcrumb"><span class="delim">/</span>|</li>|*|<li><span class="delim">/</span>|</li>|*|<li class="lastcrumb"><span class="delim">/</span>|</li>


Готовый скрипт выглядит так:
#includeLibs.myFunc = fileadmin/userfuncs/tools.php
lib.breadcrumb = HMENU
lib.breadcrumb.special = rootline
lib.breadcrumb.special.range = 0|-1
lib.breadcrumb.wrap = <div id="navmenu"><ul> | </ul></div>
lib.breadcrumb.1 = TMENU
lib.breadcrumb.1{
noBlur = 1
NO.allWrap = <li> | </li>

ACT = 1
ACT.ATagParams.dataWrap = title="{field:subtitle}"
ACT.allWrap = <li class="firstcrumb"><span class="delim">/</span><a href="http://www.domain.com/" title="Home"><img src="fileadmin/templates/img/home.png" alt="Home" /></a></li>||<li class="secondcrumb"><span class="delim">/</span>|</li>|*|<li><span class="delim">/</span>|</li>|*|<li class="lastcrumb"><span class="delim">/</span>|</li>
ACT.doNotShowLink = 1 |*| 0

CUR = 1
CUR.doNotLinkIt = 1
CUR.allWrap = <li><strong> | </strong></li>
}
# Реверс пунктов меню пользовательской функцией
#lib.breadcrumb.1.itemArrayProcFunc = user_tools->reverseMenuItemProcFunc

Вот мои CSS-стили:

#navmenu ul, #navmenu ul li{
display:inline;
list-style:none;
height:30px;
line-height:30px;
}
#navmenu ul{
float:left;
}
#navmenu li{
float:right;
}

#navmenu strong{
font-size:22px;
color:#333333;
line-height:21px;
}
#navmenu .delim{
color:#333333;
padding:0 7px;
text-align:center;
}
#navmenu .secondcrumb a{
color:#333333;
}
/* end breadcrumb menu */

О себе

Моя фотография
Вадим Гиркало
Фрилансер, веб-разработчик сайтов на базе бесплатной, мощнейшей и очень гибкой CMS системы - TYPO3.
Просмотреть профиль

Позвонить мне в Skype

TOP - 3