Все главы
  1. 1 Перед началом
  2. 2 Установка
  3. 3 Страницы
  4. 4 Первый шаблон
  5. 5 Компоненты
  6. 6 Рамка сайта
  7. 7 Поля страниц
  8. 8 Списки страниц
  9. 9 Свои настройки
  10. 10 Заявка на замер
  11. 11 Живые части
  12. 12 В интернет
  13. 13 Что дальше

Рамка: один макет на все шаблоны

Скоро шаблонов станет несколько. Чтобы не повторять в каждом шапку, подвал и стили, соберём их в рамку, а шаблоны будут класть внутрь только своё.

Глава 6 из 13 · 2 минуты чтения

Что повторяется

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

Значит, вынесем всё общее в компонент-рамку. Рамка нарисует шапку и подвал, а в середину вставит то, что ей передал шаблон.

Компонент Layout

Создайте компонент Layout:

Компонент Layout
<!-- @component
Рамка сайта: заголовок вкладки, шапка, подвал и общие стили. Шаблон кладёт внутрь свою часть.
-->
<script>
  import Footer from '$components/Footer';
  import Header from '$components/Header';
  import { site } from '$core';

  let { page, children } = $props();
</script>

<svelte:head>
  <title>{page.longTitle || page.title} — {site().name}</title>
</svelte:head>

<Header />

<main>
  {@render children()}
</main>

<Footer note="кухни по вашим размерам" />

<style>
  :global(body) {
    margin: 0;
    background: #f1efeb;
    color: #1f1e1c;
    font: 18px/1.6 system-ui, sans-serif;
  }

  :global(h1) {
    font-size: 2.75rem;
    line-height: 1.05;
    letter-spacing: -0.02em;
  }

  :global(img) {
    max-width: 100%;
    height: auto;
  }

  main {
    max-width: 48rem;
    margin: 0 auto;
    padding: 0 1.5rem 2rem;
  }
</style>

Главное здесь две вещи.

  • let { page, children } = $props();: рамка получает страницу (для заголовка вкладки) и children, то есть всё, что шаблон положит между открывающим и закрывающим тегом рамки.
  • {@render children()}: «нарисуй здесь то, что передали внутрь». Именно на этом месте окажется середина каждого шаблона.

Стили заголовков и картинок стоят в :global(…): так они действуют на всю страницу. Без него стили рамки касались бы только её собственной разметки.

Base внутри рамки

Замените код Base:

Шаблон Base
<script>
  import Content from '$core/Content';
  import Layout from '$components/Layout';

  let { page } = $props();
</script>

<Layout {page}>
  <h1>{page.longTitle || page.title}</h1>
  <Content of={page} />
</Layout>

Восемь строк вместо пятидесяти. <Layout {page}> это короткая запись <Layout page={page}>: когда имя параметра совпадает с именем значения, его можно не повторять.

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