11ноября,
2010
Удобное редактирование ключевых слов (keywords) в Modx Evolution

В Modx Evolution редактирование ключевиков вынесено в отдельный таб, что, например, мне неудобно. Проще, когда прямо при редактировании документа можно их указать и сохранить документ.

Для этого понадобится всего пара штук:

1. TV-параметр. Назовём его «keywords». Это должен быть тип Text, остальное не подходит. Назначить этот TV всем документам, где должны быть ключевые слова.

2. Установленный плагин Managermanager (он уже предустановлен в релизах, начиная с версии 1.02 вроде, последняя сейчас 1.04, так что проблем с этим быть не должно).

3. Добавить всего одну строчку в mm_rules (описание правил для Managermanager):

mm_widget_tags('keywords');

4. В <head> поставить вот такую строчку:

<meta name="keywords" content="[*keywords*]">

Этот виджет для Managermanager-а позволяет собирать вводимые на сайте теги, но никто не мешает использовать его для сбора, например, ключевых слов. Вводимое новое слово в любом документе в этом TV, потом отображается уже, как слово из выборки, по которому можно просто кликнуть, выглядеть это должно примерно так:

Итого, всё создали, это самая простая настройка, означает, что, где бы ни появился этот TV, он везде будет работать, как сборщик вводимых слов.

На мой взгляд, такой вариант куда удобней, чем лазить в отдельный таб и там ковыряться с ключевиками. Тем более, что не пришлось ничего дописывать самостоятельно, всё уже есть предустановленное.

Более подробно о виджете «mm_widget_tags» есть в документации на русском.

31мая,
2010
Вся мелочь со страниц сайта в одном документе при помощи Ditto

Когда делается сайт, всегда есть какие-то мелкие вещи, которые одинаковые на всех страницах, например, небольшой блок контактной информации внизу сайта, фразы и названия кнопок, текст кнопки выхода из системы, сменный фон на страницах, единый для всего сайта.

Самый простой вариант: Забить их жёстко и не давать менеджеру сайта возможность их редактировать.

И другой вариант: Все необходимое собрать в одном документе, вписать в TV-параметры и вызывать в нужным местах.

Выглядит это примерно так:
Делается шаблон Settings (можно его оставить пустым), cоздаётся документ в дереве сайта, тоже Settings (Я так его называю, чтобы сразу было понятно, что и для чего он), отключается отображение в меню, тогда не вылезет нигде в меню, присваивается шаблон, описанный выше, этому шаблону назначаются все необходимые TV-параметры. Их можно заполнить заранее или потом.

А в шаблоне любой страницы сайта пишется вызов Ditto, где будет, например, блок контактной информации:

[[Ditto? &documents=`20` &tpl=`settings`]]

Кэшируемый вызов Ditto, из документа Settings, у которого, ID-номер, например, 20, вызывается всё необходимое, tpl — шаблон для вывода на страницах сайта.

Шаблон вывода может выглядеть так:

<div>
<h3>[+longtitle+]</h3>
<p>[+introtext+]</p>
</div>

Заголовок для блока берётся из поля Longtitle, а сама контактная информация из Introtext-а. Достаточно заполнить их только в документе Settings, и они будут везде отображаться одинаково. И у клиента будет возможность самостоятельно их поменять, не придётся копаться, ни в чанках, ни в TV-параметрах или просить разработчика это сделать.

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

1мая,
2010
Проблема с AjaxSearch в связке с YAMS в Modx

Как оказалось, AjaxSearch нигде и ничего не ищет, когда системные поля Modx-а YAMS заменяет на TV-параметры.

На официальном форуме предлагается решение в подробностях, которое у меня так и не заработало. Всё это делалось на версии Modx Evolution 1.0.3.

А нашлось оно совершенно случайно (как обычно, впрочем). Надо было поставить чуть постарше версию AjaxSearch-a.

А именно версию 1.8.4. Она лежит в Previous Releases AjaxSearch-a.
Либо вот прямая ссылка на неё.

Как выглядит сам вызов:

На всех страницах сайта (ну, или на тех, где поле для поиска нужно) разместить вызов сниппета:

[!AjaxSearch? &parents=`0` &mbstring=`0` &AS_landing=`25` &addJscript=`0` &extract=`0` &AS_showResults=`0` &ajaxSearch=`0` &language=`(yams_mname)` &withTvs=`+:pagetitle_en,longtitle_en,introtext_en,description_en,content_en,pagetitle_ru,longtitle_ru,introtext_ru,description_ru,content_ru` &tplLayout=`search_tpl`!]

mbstring я отключаю сразу, оно у меня не работает. Поиск без перезагрузки я не проверял, он не нужен мне в 99%, а то и во всех 100% случаев, вроде как он всё равно корректно не работает. Ну, а дальше, собственно, куда будет выводиться результат поиска, на каком языке будет всё описание и, то, по каким полям AjaxSearch будет искать. Ну и сами TV-параметры, которые создаёт YAMS и не находит AJAxSearch.

Шаблон формы поиска стандартный:

[+as.showForm:is=`1`:then=`
<form [+as.formId+] action=[+as.formAction+]«„ method=“post»>
<fieldset>
<input type="hidden" name="advSearch" value=[+as.advSearch+]«„ />
<label for=“ajaxSearch_input»>
<input id="ajaxSearch_input" type="text" name="search" value=[+as.inputValue+]«[+as.inputOptions+]„ />
</label>
<label for=“ajaxSearch_submit»>
<input id="ajaxSearch_submit" type="image" src=[(site_url)]«images/search.gif» name="sub" value=[+as.submitText+]«« />
</label>
</fieldset>
</form>
`+]
[+as.showIntro:is=`1`:then=`
<p id="ajaxSearch_intro">[+as.introMessage+]</p>
`+]
[+as.showResults:is=`1`:then=`
[+as.results+]
`+]

Страница вывода результатов:

[!AjaxSearch? &mbstring=`0` &AS_showResults=`1` &ajaxSearch=`0`, &AS_landing=`25`, &AS_showForm=`0` &language=`(yams_mname)` &withTvs=`+:pagetitle_en,longtitle_en,introtext_en,description_en,content_en,pagetitle_ru,longtitle_ru,introtext_ru,description_ru,content_ru` &tplResult=`searchresult_`!]

Шаблон вывода результатов:

<a href=»(yams_doc:[+as.id+])» title=[[YAMS? &get=`content` &from=`pagetitle` &docid=`[+as.id+]«`]]»>[[YAMS? &get=`content` &from=`pagetitle` &docid=`[+as.id+]`]]</a>
[+as.descriptionShow:is=`1`:then=`
<span>[+as.description+]</span>
`+]
[+as.extractShow:is=`1`:then=`
<div><p>[+as.extract+]</p></div>
`+]
[+as.breadcrumbsShow:is=`1`:then=`
<span>[+as.breadcrumbs+]</span>
`+]

Тут стоит обратить внимание, что вызовы плейсхолдеров AjaxSearch-а заменяются на вызовы сниппета YAMS.

Чтобы ссылка работала верно, она обязательно должна быть заменена на (yams_doc:[+as.id+])

Ну, а показать title или заголовок, то надо вызывать сниппет YAMS:

[[YAMS? &get=`content` &from=`pagetitle` &docid=`[+as.id+]`]]

Такой поиск работает корректно, ищет и находит и правильно ссылается на страницы из результатов поиска.

29апреля,
2009
Ищем выход, да не там

На работе в сортире над раковиной повесили табличку:
«Ля-ля, не смывать воду после уборки в раковину, а также остатки от кофе, ля-ля и так далее».

Вот почему нельзя было поставить нормальные трубы, чтобы вот этот капилляр, который идёт от раковины в канализацию, не засорялся. Там экономии-то две копейки, а всё равно поскупились на нормальные.

Я дома канализацию всю проводил сам, поставил нормальные трубы, сливаю кофейную гущу в раковину уже не первый год, ни разу у меня не засорялось.

Понятно, типа дома для себя делаешь, а тут для всех, все ходят, гадят. И соответственно, чем один раз сделать и надолго, лучше повесим тупые таблички, на которые всё равно всем насрать. Всё равно в раковину будут сливать всё, что под руку попадёт. Но зато администрация считает, что их совесть чиста, табличка-то висит.

Вот, в принципе, один из примеров, что у нас хотят деньги только получать, не хотят обеспечить должный уровень. Потому что лень, потому что для этого надо чуть пошевелиться, а не просто сделать вид для статусности. Причём, у нас всё делается для статусности. Раковина есть, есть, а как уж она там фурычит, дело второе. И так везде.

Также и в том, чем я занимаюсь — главное картинку погуще, а то, что сайт, это совокупность очень многих вещей, всем насрать, потому что никто этого не знает, знать не хочет и ещё остальных заставляет плевать на это.

И дома у нас также строили, фасад вылижут, а внутри потолки на голову уже через год падают.

Пока всё будет делаться для статусности, ничего и никогда не будет хорошо, надо делать свою работу правильно, а не только норовить срубить бабла, запудрив мозги тем, что видно снаружи.

Если бы известнейшие концерны автопрома также собирали машины, представляю, чем бы это обернулось на дорогах.

21февраля,
2009
Как я делаю галерею в ModX

Уверен, что я не первооткрыватель, но всё же.
Есть готовый сниппет галереи — Maxigallery, но на мой взгляд он чересчур далёк от нормальной галереи.
Потому для вывода изображений я использую Ditto. Как оказалось, создать удобный шаблон, куда выводить уменьшенный вариант и вешать линк на полный размер при помощи Ditto очень просто. Если нет желания готовить маленькие версии картинок, то тут DirectResize в помощь, он делает это автоматически.
Собственно, о самом выводе.
Делаем в админке новый документ-контейнер «Gallery», где будут лежать все изображения галереи. Контейнер, потому что каждая фотография будет, как подраздел.
Задаём контейнеру необходимый шаблон, в шаблон же пишем вывод Ditto:

[!Ditto? &startID=`1` &tpl=`gallery_chunk` &sortBy=`menuindex`!]

Теперь пояснения:

&startID=`1` — это ID-номер контейнера, из которого будут браться вложенные документы для формирования галереи.

&tpl=`gallery_chunk` — шаблон (чанк) вывода предпросмотра и ссылки на полное изображение. Как его сделать, будет описано ниже.

&sortBy=`menuindex` — сортировать документы по порядковому номеру в меню. Выбрал именно этот вариант, потому что по дате не устраивает, а писать отдельные tv-параметры не вижу смысла, если уже при создании документа можно задать порядковый номер. Также можно ещё прописать &sortDir=`ASC или DESC`. ASC — по возрастанию DESC — по убыванию. По умолчанию DESC.

Чанк вывода «gallery_chunk»:

Он достаточно маленький. Для начала создадим два tv-параметра: [*image_preview*] и [*big_image*], на самом деле, называть можно, как угодно, главное вывести их в чанк «gallery_chunk». Задаём обоим «тип ввода» — Image и ставим галочку на тот шаблон, для которого хотим, чтобы они были доступны, сейчас это шаблон «gallery».
Затем делаем новый чанк, называем его «gallery_chunk». В него пишем:

<a href=[+big_image+]«„ rel=“lightbox» title=[+title+]"">
<img src=[+image_preview+]"" alt=[+title+]"" />
</a>

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

Пояснения:

подстановщики в Ditto пишутся не со *, а с +, но сути это не меняет, конечно.

href=[+big_image+]«„ — ссылка на большое изображение.

rel=“lightbox» — я любитель подключать для просмотра картинок lightbox, в ModX он есть предустановленный, можно вызывать его иначе, но я верстаю макеты, учитывая сразу его наличие.

title=[+title+]"" и alt=[+title+]"" — можно взять любое поле, заполняемое при создании очередной фотографии, title — для lightbox-а, а alt по стандарту и поясняющий текст к картинке.

src=[+image_preview+]"" — это, собственно, сама маленькая картинка.

Теперь заходим в админку и в документе «Gallery» создаём дочерний документ, назначаем ему шаблон gallery, потому что именно к нему привязаны эти два tv-параметра, при помощи которых будут выводиться изображения. Вписываем заголовок. Под текстовым полем появились ещё два поля для подгрузки картинок, загружаем маленькую картинку и большую. После сохранения уже работает.

P.S. Когда залогинены в системе, не пытайтесь смотреть работу лайтбокса через этот же браузер, скрипты блокированы. Откройте в другом браузере, либо скиньте логины.

P.P.S. Если использовать для этих целей DirectResize, то изображения грузятся прямо в поле основного содержимого документа, и маленькое изображение генерируется автоматически, отпадает надобность в дополнительных tv-параметрах.

1февраля,
2009
Самые-самые баги IE6

Решил подсобрать самые распространённые баги, выдаваемые Internet explorer-ом 6, с которыми сталкиваешься в процессе вёрстки. Если знать заранее, где они могут вылезти, то можно и верстать так, чтобы не пришлось потом судорожно выискивать ошибку.

Большинство стилей для IE6, которые отличаются, лучше прописывать в отдельный css-файл через conditional comments в html-файл между тегов <head></head>, например, так:

<!--[if lte IE 6]> <style type="text/css" media="all">@import url ('/css/ie.css');</style> <![endif]-->

Где, if — команда «если», lte — ниже и эта версия включительно, IE 6, соответственно, название версии браузера.

А теперь сами ошибки:

Удваивающийся margin
— Либо вручную прописывать половину от margin-a, либо пользоваться padding-ами внешних блоков, избегая появления таких ошибок.

Схлопывающийся блок, если внутри него есть элементы с float
— Обычно это устраняется добавлением внешнему блоку overflow: hidden. В IE6 это не сработает, если не указана ширина. Соответственно:
1. Указать ширину.
2. Прописать display:inline-block; — использовать в тех случаях, когда жёстко задать ширину нет возможности.

Трёхпиксельные отступы у «плавающего» блока
— Прописать блоку отрицательные отступы — margin: 0 -3px;

Ненужные отступы у картинок
— Либо задать <img> float, либо display: block;

Минимальная и максимальная ширина
— Используется специальный хак, потому что других способов реализации нет:
Max-width:
width:expression (document.body.clientWidth > 400? «400px»: «auto» );

Min-width:
width:expression ((document.documentElement.clientWidth || document.body.clientWidth) < 1000? «1000px»: «auto»);

Минимальная и максимальная высота
Min-height:
height:expression (this.scrollHeight < 200? «200px» : «auto»);

Max-height:
height:expression (this.scrollHeight > 200? «200px» : «auto»);

Если пишете эти свойства в общий css, то обязательно ставьте в конце класса, иначе другие свойства внутри этого класса могут вообще не работать.

Отступы в пустых блоках
— Это резервированное место равное высоте и ширине одной буквы, размер которой задан главным.
1. Обнуляется font-size: 0;
2. Либо, если внутри блоки с нежелательными отступами (IE6 берёт отступ из CSS и добавляет резервированный), в html-файле расположить их один за другим, не оставляя между ними пробелов и переносов строки.

Нижний margin не срабатывает
— По-возможности использовать padding, либо верхний margin (верхний всегда срабатывает). Если ни то, ни другое невозможно в данный момент, то border-bottom под цвет фона или clear:both;.

Обнулить резервированные отступы у рамок ячеек таблиц
— border:0, как оказалось недостаточно. Свойство border-collapse: collapse — обнуляет полностью резервируемые отступы.

Дублирование последнего блока, если подряд идёт много элементов с float
— Такое встречается, если задана жёсткая ширина контейнера, в котором элементы с float. в этом случае дублированный блок перескакивает на следующую строку. Его можно спрятать через overflow: hidden за границей контейнера.

Данные решения соответствуют современным стандартам, как css, так и html. За исключением хаков: min-height, min-width, max-height, max-width.

P.S. возможно, список пополню, если всплывёт ещё что-то.

6января,
2009
Два фона, height: 100% и больше

Я продолбался битых 4 часа, пытаясь выяснить, что делать с двумя блоками, которые должны минимально занимать 100% высоты экрана, а также растягиваться свыше 100%, если контента больше. В общем, новые сутки я встретил в компании кучи запущенных браузеров, непослушных блоков, чашки кофе, от крепости которого глаза лезут на лоб и нежелания спать, пока проблема всё же не будет решена.

Как обычно, всё началось с того, что вылез баг в ие6. С данной проблемой я уже сталкивался, когда верстал макет Ecoorganic. Там проблема решалась проще, потому что блоку с фоном, лежащим под всем контентом, а также выступающим снизу, если текста на странице мало, можно было задать минимальную высоту в фиксированном значении. В этом же случае, мне надо было полностью не зависеть от содержимого и размера окна.
Сделав стандартный набор в css для html и body:

<span>html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}</span>

я также прописал для html и body этакий «быстрый хак» — _height:100%;. Утверждают, что IE6 неправильно обрабатывает высоту, потому подобная запись на него действует, как свойство min-height для новых и нормальных браузеров. Однако, нет. Работает оно вообще не так, и точно не так, как хотелось бы.
Второй фон, который должен был занимать ширину и высоту поверх первого на 100%, я положил в div с классом:

<span>.layout {
text-align: left;
background: url(images/bck_ill.gif) center center;
width: 100%;
height: 100%;
min-height: 100%;
_height:100%;
}</span>

Вроде как во всех браузерах нормальное отображение, кроме Firefox 2, как ни странно. Внутри div-а с классом .layout находились блоки с float, что дало обычный в этих случаях результат — div сложился и контент вывалился из блока, образовав огромную дыру в пару экранов под футером сайта.
Естественно, что используют в этих случаях, я использовал для блока overflow: hidden;. Overflow отсёк лишнее, и блок занял нормальную высоту 100%, а также стал растягиваться по высоте контента за 100% высоты. Но в IE6 это выглядело совсем иначе: overflow:hidden; срезал всё, что ушло за высоту 100%, скроллбар стал неактивен. В общем, превышать содержимое страницы больше, чем один экран, стало невозможно.
Вот за решением этой проблемы и поиском, а также ползуясь методом тыка, я провёл ещё пару часов.
Ответ нашёлся весьма спонтанно. Убрав свойства min-height:100% у html и body и добавив .layout-у свойство display: table. Избавился везде от «быстрого хака» — _height:100%;.
Обработка свойств, назначенных html и body не требует указания минимальной величины, чтобы блок продолжал тянуться, он занимает всё пространство, которое занимает контент.
У блочного элемента с классом .layout указанное свойство min-height:100% для нормальных браузеров заставляет его растягиваться на 100%, а свойство display:table;, соответственно, заставляет блочный элемент вести себя, как табличный, что корректно работает и в IE6, и в остальных браузерах.

Окончательный код CSS:

<span>html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}</span>

body {
 background: #FDF6DE url(images/bck.gif);
}
.layout {
 background: url(images/bck_ill.gif) center center;
 width: 100%;
 height: 100%;
 min-height: 100%;
 display: table;
}

Окончательный код HTML:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Some site</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="inside.css" type="text/css">
</head>
<body>
<div class="layout">
Content
</div>
</body>
</html>

Этот вариант вёрстки был проверен в браузерах: Firefox 2, Firefox 3, Google Chrome, Safari for Windows, Safari for Mac, Opera 9.24, IE7, IE6 — везде отображается корректно.
HTML и CSS успешно прошли валидацию.

3января,
2009
Шрифты и веб

Подтолкнул меня написать об этом поиск полезной информации по теме системных шрифтов.
Попытка найти некую общность между операционными системами и отображением текста на веб-страницах, особым успехом не увенчалась. Каждая ОС отображает шрифты, как разработчики «положили», к тому же ещё и браузеры на свой лад любят менять вид.
Если, скажем, Макинтоши и Windows-платформы отличает сглаженные-несглаженные, то с Линуксами всё гораздо хуже. В Linux даже и близко нет таких шрифтов, к которым привыкли все, просматривая веб-страницы на Windows-платформах и Macintosh-ах. Устанавливать их будут специально только те, кому это действительно нужно. Можно, конечно, сказать, что пользователей nix-не так много, зачем, мол, из-за них ещё голову ломать. Проблема возникает в том, что большинство шрифтов там довольно размашистые, если подгонялся текст в какие-то рамки, то в большинстве случаев он просто вылезает за границы блока. Konqueror адекватно и прилично отображает весь текст, за исключением того, что он просто заменяет все шрифты на жёстко заданные в настройках.
Выбирая подходящие шрифты, набрал совсем немного тех, которые, в принципе, на большинстве компьютеров будут отображаться, и будут отображаться нормально.

  • Tahoma font
  • Verdana font
  • Arial font
  • Times font
  • Courier font
  • Georgia font

На мой взгляд, этих шести шрифтов более чем достаточно для отличного оформления текстовых блоков, они хорошо читаются, к ним уже все привыкли, да и текст лучше подавать в удобном виде, а не развлекаться с начертанием каждой буквы.
Для подачи небольших текстов, как заголовки, слоганы, краткие подсказки итд, есть масса способов иных — флэш, javascript-ы, графикой, в конце концов.
И чтобы избежать совсем уж непредсказуемых результатов, надо прописать в таблицу стилей тип начертания:

  • serif — для шрифтов с засечками.
  • sans-serif — для рубленых шрифтов.
20декабря,
2008
modX CMS

Немного об opensource-разработке — системе управления сайтом.
Эта CMS, как её некоторые называют CMF, сравнительно молодая, но успешно набирающая обороты.

Чем хороша эта система:

  • Удобна в управлении
  • Достаточно легко и доступно создаются шаблоны (при должном знании HTML)
  • Использование дополнительных модулей (сниппетов)
  • Комбинации сниппетов дают интересные возможности
  • Удобные разграничения прав пользователей
  • Не ресурсоёмкая

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

Недостатки:

  • Отсутствует возможность создания многоязычного сайта (есть сниппет эмуляции)

Пока ещё существенных недостатков не встречал.

Ссылки по теме:

Русский сайт modX — http://modx.ru/
Русскоязычное коммьюнити modX — http://www.modx-cms.ru/
Документация и руководство на русском языке на Вики — http://ru.wikibooks.org/wiki/MODx
Ещё одно русскоязычное сообщество — http://xtetis.com/
ModX на Хабре — http://habrahabr.ru/blogs/modx/
Русифицированная и отлаженная сборка modX пользователя VIT — http://www.modx-cms.ru//forum/comments.php?DiscussionID=562
Репозиторий плагинов и сниппетов — http://modxcms.com/resources.html
Официальный сайт modX на английском языке — http://modxcms.com/
Англоязычное коммьюнити — http://modxcms.com/forums/index.php

P.S. На сборку своего первого сайта с нулевой подготовкой я потратил порядка недели, и ещё дня три на отладку и исправление недоделок. modX оказалась очень уж понятной и доступной даже такому неподготовленному пользователю, как я.

23ноября,
2008
Схлопывающийся div

В принципе, достаточно много об этом написано, найдено решение давно.
В CSS для блока, который не имеет фиксированной высоты и в нём находятся элементы с float, прописывается:

overflow: hidden;

Это свойство по какой-то причине заставляет блок растягиваться на высоту элементов содержащихся внутри. Однако, это свойство работает в IE6, если блоку указана ширина. Если таковой не имеется, то в этом несчастном браузере не происходит никаких положительных изменений. Можно указать блоку, конечно ширину, либо в процентах, либо жёстко фиксированную. Однако, если у блока есть margin или padding, а надо, чтобы блок был во всю ширину страницы, то результат не заставит себя ждать — блок уползёт за границы экрана и появится горизонтальный скролл.
Но решение всё же есть — свойство блока display. То, которое не понимает Mozilla Firefox (Mozilla Firefox 3 уже понимает), но понимает IE6 — display: inline-block;
Это свойство заставляет в IE6 блок растягивать на нужную ширину и высоту.
Чтобы избежать лишних ошибок в других браузерах, подобные детали стоит вынести в отдельный цсс, и при помощи conditional comments подключить это свойство.

P.S. Иногда всё-таки оно не срабатывает(что бывает крайне редко) и блок схлопывается, после обычной перезагрузки страницы, всё встаёт на свои места.