SquareSpace — коммерческая CMS, объединяющая в себе удобный WYSIWYG-редактор, блог-платформу, функционал интернет-магазина и хостинг. Про все преимущества этого продукта надеюсь расскажет автор этого поста, как он и обещал — ну а я хотел бы поведать тот минимум, который поможет быстро сориентироваться при самостоятельной разработке сайта на Squarespace. Если вам интересно, как в кратчайшие сроки приступить к разработке — прошу под кат.
При создании сайта на SquareSpace можно воспользоваться более, чем дюжиной встроенных шаблонов. Все они очень хорошо проработаны, имеют мобильную версию. Благодаря настройкам и визуальному редактору (прямо на странице можно поменять и css-код) можно быстро добиться желаемого результата, и простые дизайны или несложные посадочные страницы получатся быстро, фактически просто клацая мышью. Но если вы любите все держать под контролем и понимать, что же творится «под капотом», да и дизайн сложный — то необходимо в настройках своего аккаунта (кроме случая, если вы сразу зарегистрировали платный) перейти на вкладку «Developer» и зарегистрироваться разработчиком.
Вот теперь-то можно приступать к разработке — ваш сайт теперь все время доступен, только по адресу расположена заглушка, предлагающая ввести капчу или логин/пароль для входа. Для простоты понимания при создании сайта можно воспользоваться «голым» шаблоном для разработчика, а можно пойти на маленькую хитрость — выбрать напоминающий будущий дизайн и функционал шаблон, а уж потом включить developer-режим сайта в настройках, что может существенно сократить время разработки (и подсмотреть как-что реализовано).
Включение developer-режима сайта
После включения нам становится видна информация с данными для подключения, основная информация о шаблоне, об используемых коллекциях, Githistory и так далее. На этой же странице будут видны основные ошибки, если что-то пойдет не так в процессе разработки.
Основная информация после включения developer-режима
Итак, как видим, имеем два способа для подключения и отладки: Git и SFTP. Тут уж кому как удобнее (или как требует работодатель), но для несложных проектов лично мне проще пользоваться SFTP, хотя несомненный плюс Git — возможность по хорошо комментированным коммитам сориентироваться что же пошло не так и вернуться к более ранней версии. Так что просто настройте SFTP-соединение в вашей любимой IDE или редакторе и синхронизируйте локальную и удаленную версии (для пользователей IDEA и продуктов от JetBrainsвсе очень просто — Tools-> Deployment -> Type: SFTP -> Хост/Порт/Логин/Пароль -> выбрать корень сайта. Также не забудьте замаппить корень локального проекта на вкладке Mappings, если хотите включить Automatic Upload по Ctrl+S).
Все сайты, разрабатываемые на SquareSpace, по-умолчанию содержат: html5shiv.js, modernizr.js, и normalize.css, вещи нужные, заботится об этом нам не надо. Так же «из коробки» на стороне сервера работает Less-препроцессор — можно смело использовать синтаксис Less, можно создавать css-стили в разных файлах — пользователю сервер отдаст один объединенный css-файл. Тоже самое касается и Javascript — по-умолчанию используется фреймворк YUI3, но вы можете подключать свой любимый фреймворк или скрипты — на выходе они тоже будут минифицированы в один файл. Шаблонизатор по-умолчанию — Json-T.
Структура шаблона выглядит примерно так:
Структура шаблона
1.Главный конфигурационный файл template.conf
Я начну с корня проекта, так как именно здесь располагаются самые важные для отображения сайта настройки. Сердце шаблона — конфигурационный файл template.conf. В этом файле по желания задается имя шаблона и авторство, а также здесь указывается разметка (Layouts) вашего сайта, навигация (Navigation) по сайту и используемые стили для отображения. Выглядит это примерно так:
{
"name" : "Something",
"author" : "michael",
"layouts" : {
"Default" : {
"name" : "Default",
"regions" : [ "header", "content", "footer" ]
},
"Home" : {
"name" : "Homepage",
"regions" : [ "header", "contenthome", "events", "footer" ]
},
"SidebarLeft" : {
"name" : "WithLeftSidebar",
"regions" : [ "header", "contentwithsidebar", "footer" ]
},
"SidebarLeft2" : {
"name" : "WithLeftSidebar2",
"regions" : [ "header", "contentwithsidebar2", "footer" ]
}
},
"navigations" : [ {
"title" : "Main Navigation",
"name" : "mainNav"
}, {
"title" : "Secondary Navigation",
"name" : "secondaryNav"
} ],
"stylesheets" : [ "base.less", "typography.less" ]
}
Содержимое template.conf
Как видим, уже на этом этапе желательно предполагать, как будут выглядеть страницы сайта, какой будет контент и так далее. Это позволит сразу выделить и задать нужные разметки и регионы (Regions) для страниц. В данном конкретном случае заданы такие layout'ы:
- Default. В него будут подключены регионы «header», «content», «footer». Будет использоваться по-умолчанию при создании любых страниц
- Home. Подключены «header», «contenthome», «events», «footer» регионы. Мне удобно было создать эту разметку отдельно для домашней страницы, так как она содержит отдельные блоки, которые больше нигде не повторяются и их дизайн сильно отличается от остальной части сайта
- SidebarLeft Сюда включены регионы «header», «contentwithsidebar» и«footer»
- SidebarLeft2По сути тоже, что и SidebarLeft, но содержимое собственно сайдбара сильно отличается — поэтому решено вынести это как отдельную разметку.
В дальнейшем, при создании страницы можно будет выбрать ту или иную разметку уже в визуальном режиме.
Навигация именуется для удобства отображения этих секций непосредственно в админ-панели сайта, и в дальнейшем подключать ее нужно по имени, которое вы дали. Задавать несколько секций целесообразно, если у вас например разные блоки навигации, скажем, в шапке сайта и подвале или сайдбаре.
В последнем пункте файла template.conf вы указываете, какие стили из папки styles использовать. По умолчанию в этой папке уже лежит reset.css (он же normalise.css) и его указывать не нужно, он подключится и так.
2. Файлы регионов (Regions)
В простейшем случае, разметка может состоять из одного региона, назовем его site.region. Содержимое его было бы примерно следующим:
<!doctype html>
<html>
<head>
{squarespace-headers}
</head>
<body class="{squarespace.page-classes}" id="{squarespace.page-id}">
<header id="header">
<h1><a href="/">{website.siteTitle}</a></h1>
<squarespace:navigation navigationId="mainNav" template="navigation" />
</header>
<div id="canvas">
<section id="page" role="main">
{squarespace.main-content}
</section>
<aside id="sidebar">
<squarespace:block-field id="sidebarBlocks" />
</aside>
</div>
</body>
</html>
Содержимое site.region
Не сильно вдаваясь в теги SquareSpace и синтаксис JSON-T и так становится ясно, что создается минимальная разметка страницы с шапкой и сайдбаром. Но я рекомендую функционально разграничивать отдельные области сайта — это делает проект более сопровождаемым, самому же легче потом вносить правки, не говоря о том, какое одолжение вы делаете человеку, которому придется работать с этим после/вместо вас.
Таким образом файл header.region мог бы выглядеть так:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1">
<!--INCLUDE SQS SCRIPTS, META TAGS AND USER CONTENT FROM THE CODE INJECTION TAB-->
{squarespace-headers}
</head>
<body id="{squarespace.page-id}" class="{squarespace.page-classes}">
<!--HEADER-->
<header class="navbar navbar-default navbar-static-top navbar-inverse">
<div class="container fade-in">
<squarespace:navigation navigationId="mainNav" template="nav" />
</div>
</header>
Файл header.region
Здесь конструкция {squarespace-headers} включает мета-теги для поисковиков и соцсетей, подключает squarespace-скрипты и позволяет дополнительно вставить код в визуальном режиме. Тегом <squarespace:navigation navigationId=«mainNav» template=«nav» /> подключается секция mainNav, используя как шаблон файл nav.block из каталога blocks.
Таким же образом создаются и остальные файлы *.region — создаете необходимую разметку и подключаете необходимый блок Squarespace. Этими блоками могут быть:
- файлы *.block . Как и примере с header.region можно подключить, например, отдельную секцию навигации для подвала или сайдбара (указав соответственное имя)
- теги Squarespace. Например, указав {squarespace.main-content} , подключим содержимое создаваемых вами страниц в визуальной части сайта.
Среди самых полезны тегов я бы выделил такие:
- <squarespace:block-field id=«blockName» columns=«12» />. Создает пустой блок, указав количество columns=«12» мы растянем его на всю возможную ширину родительского элемента (да, у Squarespace 12-и колоночная grid-system как и у многих популярных фреймворков, я коснусь этого ниже). В этот пустой блок в визуальном режиме вы сможете позднее добавить любой из виджетов Squarespace или собственный html/js-код.
- <squarespace:query collection=«blog» limit=«3»></squarespace:query>. Сделает запрос к указанной коллекции (в данном случае blog), это может быть ваша галерея, блог, список товаров и тому подобное, и вернет указанное в limit количество объектов в JSON. Дальше их просто распарсить все тем же JSON-T и вывести на главной странице, в сайдбаре или где вздумается. В данное время кэширование запросов не организовано, рекомендуется не усердствовать с этим делом.
3. Блоки (Blocks)
Фактически блоки — то же, что и регионы. И все сказанное выше к ним абсолютно применимо, и при желании можно обходится без них. И все же рекомендую их использовать — это более наглядно, более структурировано. Использовать отдельные файлы *.block для шаблонов навигации — милое дело. Так что давайте рассмотрим гипотетический navigation.block и разберемся, что к чему.
navigation.block
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span>
<span class="icon-bar"></span><span class="icon-bar"></span>
</button>{.section website}<a class="navbar-brand" href="/">{.section logoImageUrl}<img src="{logoImageUrl}?format=original" alt="{siteTitle}"/>{.end}{.end}</a></div>
{.section items}
<div class="collapse navbar-collapse navbar-ex1-collapse middle">
<ul class="nav navbar-nav navbar-right">
{.repeated section @}
{.folder?}
<li class="folder dropdown">
<a class="{.if folderActive}folder-active{.end}" role="button" data-toggle="dropdown" href="#">{collection.navigationTitle}<span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
{.repeated section items}
{.collection?}
<li class="{collection.typeLabel}-collection" role="presentation">
<a href="{collection.fullUrl}" class="{.section active}active{.end}" role="menuitem" tabindex="-1">{collection.navigationTitle}</a>
</li>
{.end}
{.section externalLink}
<li class="external-link">
<a href="{url}"{.section newWindow} target="_blank"{.end}>{title}</a>
</li>
{.end}
{.end}
</ul>
</li>
{.or}
{.collection?}
<li class="{collection.typeLabel}-collection">
<a href="{collection.fullUrl}" class="{.section active}folder-active{.end}">{collection.navigationTitle}</a>
</li>
{.end}
{.section externalLink}
<li class="external-link">
<a href="{url}"{.section newWindow} target="_blank"{.end}>{title}</a>
</li>
{.end}
{.end}
{.end}
</ul>
</div>
{.end}
Файл navigation.block
Сразу оговорюсь, что здесь использовался Bootstrap 3, поэтому вы видите знакомые/незнакомые классы. Здесь основательно используется JSON-T-разметка, уточним же, что за что отвечает.
{.section website}<a class="navbar-brand" href="/">{.section logoImageUrl}<img src="{logoImageUrl}?format=original" alt="{siteTitle}"/>{.end}{.end}</a>
Этой конструкцией мы «открыли» глобальную область видимости нашего сайта, проверили задан ли логотип (загружается в визуальных настройках) и собственно отобразили его.
{.section items}
<div class="collapse navbar-collapse navbar-ex1-collapse middle">
<ul class="nav navbar-nav navbar-right">
{.repeated section @}
{.folder?}
<li class="folder dropdown">
<a class="{.if folderActive}folder-active{.end}" role="button" data-toggle="dropdown" href="#">{collection.navigationTitle}<span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
{.repeated section items}
{.collection?}
<li class="{collection.typeLabel}-collection" role="presentation">
<a href="{collection.fullUrl}" class="{.section active}active{.end}" role="menuitem" tabindex="-1">{collection.navigationTitle}</a>
</li>
{.end}
{.section externalLink}
<li class="external-link">
<a href="{url}"{.section newWindow} target="_blank"{.end}>{title}</a>
</li>
{.end}
{.end}
</ul>
</li>
Здесь мы обращаемся конструкцией {.section items} ко всем нашим страницам на сайте, которые в визуальных настройках вы поместили в секцию навигации. Дальше включаем «цикл» — {.repeated section @} в котором будет опрашиваться каждый item (страница, папка со станицами, блог, коллекция, галерея, продукты или что-либо созданное вами дополнительно). Собственно, {.folder?} и {.collection?} и тестируют, чем есть текущий item.
Если это папка (folder), то создается ссылка на нее и запускается еще цикл {.repeated section items}, в котором происходит опрос теперь уже содержимого данной папки (а это могут быть либо просто страницы, либо коллекции, либо материалы с внешней ссылкой). Здесь следует заметить, что на данный момент поддерживается только один уровень вложенности, так что если у вас много уровней в меню, то нужно хитрить.
Удобный момент — можно протестировать активна ли данная папка или ссылка конструкциями {.if folderActive}folder-active{.end} и {.section active}active{.end} и присвоить им нужный класс (и описать нужными стилями). Очень удобно — не надо создавать свой велосипед со сравнением текущего адреса и адресов ссылок в навигации.
{.or}
{.collection?}
<li class="{collection.typeLabel}-collection">
<a href="{collection.fullUrl}" class="{.section active}folder-active{.end}">{collection.navigationTitle}</a>
</li>
{.end}
{.section externalLink}
<li class="external-link">
<a href="{url}"{.section newWindow} target="_blank"{.end}>{title}</a>
</li>
{.end}
{.end}
{.end}
</ul>
</div>
{.end}
Этот последний кусок кода делает то же самое, что мы провернули внутри цикла опроса папки — проверяет оставшиеся элементы, создает на них ссылки, задавая нужные классы и атрибуты (для внешних ссылок). Важно проследить, чтобы все секции были закрыты ({.end}), иначе не заработает правильно.
4. Коллекции (Collections)
Коллекции в Squarespace — это суть та же папка, только содержимое ее одного типа. Самый яркий пример — блог: все посты, по сути одинаковы, разное лишь их содержимое. В зависимости от шаблона, доступны разные коллекции, но у них всех одно устройство, разная лишь разметка внутри.
Итак, в идеале коллекция состоит из трёх файлов (рассматриваем блог):
- blog.conf. Содержит основные настройки коллекции
- blog.list. Отвечает за отображение списка всех элементов коллекции. В случае блога, это к примеру список кратких выдержек (excerpt) статей со ссылками на полную версию, пагинацией, если требуется.
- blog.item. Отвечает за отображение конкретного элемента коллекции. В случае блога — полный текст статьи, ссылки на предыдущую/следующую статью, блок комментариев, соцкнопки и так далее.
Минимально для работы коллекции нужны файлы *.conf и *.item.
Дальше я приведу содержимое этих файлов без разъяснений, думаю если вы дочитались сюда, то уловили смысл построения шаблонов (комментарии и названия section говорят сами за себя).
blog.conf
{
"title" : "Blog",
"ordering" : "chronological",
"addText" : "Add Post",
"acceptTypes": ["text"],
"promotedBlocks" : [ "" ]
"icon": "blog"
}
Файл blog.conf
blog.item
{.repeated section items}
<article class="{@|item-classes}" id="article-{id}" data-item-id="{id}">
<div class="blog-wrapper">
<div class="post{.passthrough?} link-list-item{.end}">
<!--POST HEADER-->
<header>
{.if title}<h2 class="entry-title" data-content-field="title">{.passthrough?}<a href="{sourceUrl}" target="_blank">{title}<span class="passthrough">→</span></a>{.or}<a href="{fullUrl}">{title}</a>{.end}</h2>{.end}
</header>
<!--POST BODY-->
{.excerpt?}
<div class="excerpt-content">{.main-image?}
<div class="excerpt-thumb"><img {@|image-meta} /></div>{.end}
{excerpt}<div class="clearfix"></div><a class="inline-read-more" href="{fullUrl}">Click to read more ...</a></div>
<div class="clearfix"></div>
{.or}
{.section body}<div class="entry-content">{@}</div>{.end}
{.end}
<!--POST FOOTER-->
<footer class="article-meta">
<div class="article-author">
{.section author}<span class="author"><a href="{collection.fullUrl}?author={id}" rel="author"><i class="icon-user"></i>{displayName}</a><span class="delimiter">|</span></span>{.end}
</div>
<div class="article-dateline">
<i class="icon-calendar"></i><time class="published" datetime="{addedOn|date %F}">{addedOn|date %A, %B %d, %Y at %l:%M %p}</time><span class="delimiter">|</span>
</div>
<div class="shareLoveButtons">
<a href="#">{@|social-button-inline}</a>
</div>
<div class="post-entry-injection">{postItemInjectCode}</div>
</footer>
</div> <!-- / post -->
</div><!-- / blog-wrapper -->
</article>
<div class="clearfix"></div>
{.end}
<!--PAGINATION-->
{.section pagination}
<nav class="page-pagination">
<div class="content-wrapper">
{.if pagination.prevPage}<a href="{prevPageUrl}" id="prevLink"><i class="icon-chevron-left"></i> Previous |</a>
{.or}<!-- <a href="{collection.fullUrl}"><i class="icon-list"></i>{collection.title}</a> -->{.end}
<!--HOME PAGE-->
<a href="{collection.fullUrl}"><i class="icon-list"></i> Main |</a>
{.if pagination.nextPage}<a href="{nextPageUrl}" id="nextLink">Next <i class="icon-chevron-right"></i></a>
{.or}<a href="{collection.fullUrl}"><i class="icon-list"></i>{collection.title}</a>{.end}
</div>
</nav>
{.end}
Файл blog.list
blog.item
{.section pagination}
<nav class="blog-pagination">
{.section prevItem}
<a href="{fullUrl}"><i class="icon-chevron-left"></i> {title} |</a>
{.or}
<a class="disabled"></a>
{.end}
<!--HOME PAGE-->
<a href="{collection.fullUrl}"><i class="icon-list"></i> Main |</a>
<!--OLDER PAGE-->
{.section nextItem}
<a href="{fullUrl}">{title} <i class="icon-chevron-right"></i></a>
{.or}
<a class="disabled">End off posts</a>
{.end}
</nav>
{.end}
{.section item}
<article class="{@|item-classes}" id="article-{id}" data-item-id="{id}">
<div class="blog-wrapper item">
<div class="post{.passthrough?} link-list-item{.end}">
<!--POST HEADER-->
<header>
{.if title}<h2 class="entry-title" data-content-field="title">{.passthrough?}<a href="{sourceUrl}" target="_blank">{title}<span class="passthrough">→</span></a>{.or}<a href="{fullUrl}">{title}</a>{.end}</h2>{.end}
</header>
<!--POST BODY-->
<!--POST BODY-->
{.section body}<div class="entry-content">{@}</div>{.end}
<!--POST FOOTER-->
<footer class="article-meta">
<div class="article-author">
{.section author}<span class="author"><a href="{collection.fullUrl}?author={id}" rel="author"><i class="icon-user"></i>{displayName}</a><span class="delimiter">|</span></span>{.end}
</div>
<div class="article-dateline">
<i class="icon-calendar"></i><time class="published" datetime="{addedOn|date %F}">{addedOn|date %A, %B %d, %Y at %l:%M %p}</time><span class="delimiter">|</span>
</div>
<div class="shareLoveButtons">
<a href="#">{@|social-button-inline}</a>
</div>
<div class="clearfix"></div>
<div class="post-entry-injection">{postItemInjectCode}</div>
</footer>
</div><!-- /post -->
</div><!-- /content-wrapper -->
</article>
<div class="clearfix"></div>
{.end}
<!--PAGINATION-->
{.section pagination}
<nav class="blog-pagination">
{.section prevItem}
<a href="{fullUrl}"><i class="icon-chevron-left"></i> {title} |</a>
{.or}
<a class="disabled"></a>
{.end}
<!--HOME PAGE-->
<a href="{collection.fullUrl}"><i class="icon-list"></i> Main |</a>
<!--OLDER PAGE-->
{.section nextItem}
<a href="{fullUrl}">{title} <i class="icon-chevron-right"></i></a>
{.or}
<a class="disabled">End off posts</a>
{.end}
</nav>
{.end}
{.section item}
<!--COMMENTS-->
{.comments?}
<div class="comments">{@|comments}</div>
{.end}
{.end}
Файл blog.item
5. Стили (каталог Styles)
В первую очередь отмечу, что Squarespace имеет свою сетку из 12-ти колонок. Разметка подобна Bootstrap, так row = sqs-row, col-md-4 = sqs-col-4. Так что вполне можно пользоваться в разметке этим фактом, но я не встречал в документации описания этих встроенных стилей, поэтому нужно «доходить» самому. И даже если вы верстаете свои стили или используете какой-то фреймворк — Squarespace «любит» оборачивать ваши разметку своими блоками — в целом это совсем не мешает, но если что-то идет не так, как задумано, просто посмотрите в инспекторе — а не добавилось ли что-то в разметке. В остальном — все обычно, используете валидный LESS или CSS-синтаксис.
Фишкой является то, что в стилях можно использовать твики (tweaks), которые дают возможность изменять указанные вами параметры в заданных пределах в визуальном редакторе стилей, встроенном в Squarespace. Очень удобно — клиент сам потом может что-то подкрутить, настроить, да и самому часто проще перенастроить что-то именно так, а не цепляться по SFTP.
В основе твиков — LESS-переменные и JSON-объекты, в которых и заданы нужные параметры и границы. Смотрим:
// tweak: { "type" : "value", "title" : "Logo Size", "min" : 50, "max" : 150 }
@logoHeight: 75px;
.logo {
max-height: @logoHeight;
}
Твик для изменения размеров логотипа
Или разрешим менять цвет (будет всплывать удобный Color picker):
// tweak: { "type" : "color", "title" : "Text Color" }
@textColor: #444444;
body {
color: @textColor;
}
Твик для изменения цвета текста
Твики можно группировать по свойствам и категориям — в результате в визуальном редакторе получите нечто подобное:
Style Editor
6. Ассеты (Assets)
Папка ассетов служит для хранения ресурсов, и вы вольны содержать здесь необходимую графику, плагины, скрипты да в общем, что душа пожелает.
7. Скрипты (Scripts)
Здесь храним скрипты. По умолчанию здесь создан файл site.js в котором инициализирован YUI3. Все скрипты, которые хранит этот каталог, можно (и нужно) загружать через загрузчик — в этом случае ваш сайт будет отдавать один минифицированный скрипт. Делается это так (например вставляем в подвал сайта):
<squarespace:script src="plugin.js" combo="true" />
<squarespace:script src="site.js" combo="true" />
Загрузка скриптов через загрузчик
8.Страницы (Pages)
В этом каталоге хранятся статичные страницы, которые не изменить в визуальном редакторе — удобно использовать для readme.page, где можно указать основные параметры, блоки и настройки шаблона, контакты и так далее.
Заключение
Squrespace очень удобная платформа, вполне может рассматриваться как вариант, если Ваш клиент готов платить. При этом Вы получаете удобный инструмент, который обеспечивает уменьшение сроков разработки и удобный сервис.
Надеюсь, написанное выше поможет быстрее освоить платформу и приступить к разработке.