Разработка шаблона для сайта на Squarespace 6

от автора

Squarespace.com
SquareSpace — коммерческая CMS, объединяющая в себе удобный WYSIWYG-редактор, блог-платформу, функционал интернет-магазина и хостинг. Про все преимущества этого продукта надеюсь расскажет автор этого поста, как он и обещал — ну а я хотел бы поведать тот минимум, который поможет быстро сориентироваться при самостоятельной разработке сайта на Squarespace. Если вам интересно, как в кратчайшие сроки приступить к разработке — прошу под кат.

При создании сайта на SquareSpace можно воспользоваться более, чем дюжиной встроенных шаблонов. Все они очень хорошо проработаны, имеют мобильную версию. Благодаря настройкам и визуальному редактору (прямо на странице можно поменять и css-код) можно быстро добиться желаемого результата, и простые дизайны или несложные посадочные страницы получатся быстро, фактически просто клацая мышью. Но если вы любите все держать под контролем и понимать, что же творится «под капотом», да и дизайн сложный — то необходимо в настройках своего аккаунта (кроме случая, если вы сразу зарегистрировали платный) перейти на вкладку «Developer» и зарегистрироваться разработчиком.

Вот теперь-то можно приступать к разработке — ваш сайт теперь все время доступен, только по адресу расположена заглушка, предлагающая ввести капчу или логин/пароль для входа. Для простоты понимания при создании сайта можно воспользоваться «голым» шаблоном для разработчика, а можно пойти на маленькую хитрость — выбрать напоминающий будущий дизайн и функционал шаблон, а уж потом включить developer-режим сайта в настройках, что может существенно сократить время разработки (и подсмотреть как-что реализовано).

Включение developer-режима сайта

Включение developer-режима сайта

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

Основная информация после включения developer-режима

Основная информация после включения 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} , подключим содержимое создаваемых вами страниц в визуальной части сайта.

    Среди самых полезны тегов я бы выделил такие:

    1. <squarespace:block-field id=«blockName» columns=«12» />. Создает пустой блок, указав количество columns=«12» мы растянем его на всю возможную ширину родительского элемента (да, у Squarespace 12-и колоночная grid-system как и у многих популярных фреймворков, я коснусь этого ниже). В этот пустой блок в визуальном режиме вы сможете позднее добавить любой из виджетов Squarespace или собственный html/js-код.
    2. <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

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 очень удобная платформа, вполне может рассматриваться как вариант, если Ваш клиент готов платить. При этом Вы получаете удобный инструмент, который обеспечивает уменьшение сроков разработки и удобный сервис.

Надеюсь, написанное выше поможет быстрее освоить платформу и приступить к разработке.

ссылка на оригинал статьи http://habrahabr.ru/post/206484/


Комментарии

Добавить комментарий

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