Slices

Slices are typically used to compose pages with a dynamic fluid layout. You can use Slices for defining dynamic layouts in rich blog posts, landing pages, case studies, tutorials, etc.

With Slices, you give the choice to alternate certain fields (e.g. Text, Quote, Image with caption). This gives authors some freedom to organise their content; in a Medium manner.

Authors can choose and populate Slices and reorder them as needed.

The most important part in Slices, is the Choices part where you define the possible fields to use for a given Slices Zone.

Here is an example of using Slices for a rich blog post layout (Text, Image with caption, Quote) :

Choice for Slices

You can use simple fields (StructuredText, Image, Embed, etc) as well as Groups (repeatable or not) for Choices in Slices. This gives you an endless horizon of possibilities for rich layouts.

Copy
      {
  "Blog Post" : {
    "uid" : {
      "type" : "UID",
      "config" : {
        "placeholder" : "unique-identifier-for-blog-post-url"
      }
    },
    "body" : {
      "fieldset" : "Post content",
      "type" : "Slices",
      "config" : {
        "choices" : {
          "text" : {
            "type" : "StructuredText",
            "fieldset" : "Text",
            "config" : {
              "multi" : "paragraph, heading1, heading2, heading3, strong, em, hyperlink",
              "placeholder" : "Post text..."
            }
          },
          "quote" : {
            "type" : "StructuredText",
            "fieldset" : "Quote",
            "config" : {
              "placeholder" : "Post quote...",
              "single" : "paragraph"
            }
          },
          "image-with-caption" : {
            "type" : "Group",
            "fieldset" : "Post image and caption",
            "config" : {
              "fields" : {
                "illustration" : {
                  "type" : "Image"
                },
                "caption" : {
                  "type" : "StructuredText",
                  "config" : {
                    "single" : "heading3",
                    "placeholder" : "Image caption..."
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "Metadata" : {
    "author" : {
      "fieldset" : "Author",
      "type" : "Text"
    },
    "date" : {
      "fieldset" : "Post properties",
      "type" : "Date",
      "config" : {
        "label" : "Post date"
      }
    }
  }
}
    

A more advanced example, using Slices to compose a layout for landing pages, including repeatable Featured Items, repeatable Question / Answer and a Text) :

Copy
      {
  "Content" : {
    "body" : {
      "fieldset" : "Dynamic page zone...",
      "type" : "Slices",
      "config" : {
        "choices" : {
          "featured-items" : {
            "type" : "Group",
            "fieldset" : "Featured items",
            "config" : {
              "repeat" : true,
              "fields" : {
                "illustration" : {
                  "type" : "Image"
                },
                "title" : {
                  "type" : "StructuredText",
                  "config" : {
                    "single" : "heading3",
                    "placeholder" : "Item title..."
                  }
                },
                "summary" : {
                  "type" : "StructuredText",
                  "fieldset" : "Short Summary",
                  "config" : {
                    "placeholder" : "Item summary...",
                    "single" : "paragraph"
                  }
                },
                "read-more" : {
                  "type" : "Link",
                  "config" : {
                    "placeholder" : "Read more  link..."
                  }
                }
              }
            }
          },
          "faq" : {
            "type" : "Group",
            "fieldset" : "FAQ",
            "config" : {
              "repeat" : true,
              "fields" : {
                "question" : {
                  "type" : "StructuredText",
                  "config" : {
                    "placeholder" : "Question...",
                    "single" : "heading3"
                  }
                },
                "answer" : {
                  "type" : "StructuredText",
                  "config" : {
                    "placeholder" : "Answer...",
                    "multi" : "paragraph"
                  }
                }
              }
            }
          },
          "text" : {
            "type" : "Group",
            "fieldset" : "Text",
            "config" : {
              "repeat" : false,
              "fields" : {
                "content" : {
                  "type" : "StructuredText",
                  "config" : {
                    "placeholder" : "Start typing...",
                    "multi" : "paragraph"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "Metadata" : {
    "uid" : {
      "type" : "UID",
      "config" : {
        "placeholder" : "unique-identifier-for-page-url"
      }
    },
    "title" : {
      "type" : "StructuredText",
      "config" : {
        "single" : "heading1",
        "placeholder" : "Page meta title"
      }
    }
  }
}
    

Reference

type

string

Slices

fieldset

string

a user-friendly field label

config

object

objects listed below

config

choices

object

(mandatory) a field or a group of fields with their optional configuration as defined in the fields reference

Slice content indexed for full-text search queries:

Copy
      // search blog posts /blog/search?terms=term1 term2
var terms = req.query.terms;
api.query([
  prismic.Predicates.at("document.type", "blog-post"),
  prismic.Predicates.fulltext("document", terms)
], { pageSize : 10 }).then(function(response) {
  // response is the response object, response.results holds the documents
});
    
Copy
      $terms = $_GET("terms");
$response = $api->query(
    array(Predicates::at("document.type", "blog-post"), Predicates::fulltext("document", terms)),
    array('pageSize' => 10)
);
$posts = $response->getResults(); // Array
    
Copy
      Response response = api.query(
    Predicates.at("document.type", "blog-post"),
    Predicates.fulltext("document", terms) // terms is a String
).submit();
List<Document> documents = response.getResults();
    
Copy
      var response = await api.query(
    Predicates.at("document.type", "blog-post"),
    Predicates.fulltext("document", terms) // terms is a String
).Submit();
IList<Document> documents = response.getResults();
    
Copy
      response = api.query([
    Predicates.at("document.type", "blog-post"),
    Predicates.fulltext("document", terms) // terms is a String
])
documents = response.results
    

An example of integrating slices into a rich blog post:

Copy
      // using pugjs templates

div.blog-main.single.container
    for slice in postContent.getSliceZone('blog-post.body').slices
        //- Render the right markup for a given slice type.
        case slice.sliceType
            when 'text'
                div !{slice.value.asHtml()}
            when 'quote'
                span.block-quotation !{slice.value.asText()}
            when 'image-with-caption'
                 - var imageWithCaption = slice.value.toArray()[0]
                    p.block-img
                        img(src=imageWithCaption.getImage('illustration').url)
                    p
                        span.image-label !{imageWithCaption.get('caption').asText()}
    
Copy
      <?
foreach($prismicdoc->getSliceZone('blog-post.body')->getValue() as $slice) {
  //- Render the right markup for a given slice type.
  switch($slice->getSliceType()) {
    case 'text':
      echo "<div>".$slice->getValue->asHtml($linkResolver)."</div>";
      break;
    case 'quote':
      echo "<span class='block-quotation'>".$slice->getValue()->getArray()[0];
      break;
    case 'image-with-caption':
      $imageWithCaption = $slice->getValue()->getoArray()[0];
      echo "<p class='block-img'><img src='".$imageWithCaption->get("illustration")->getUrl()."></p>";
      echo "<span class='image-label'>".$imageWithCaption->get("caption")->asText()."</span>";
  }
}

    
Copy
      <c:forEach items="prismicdoc.getSliceZone("blog-post.body").getValue()" var="slice">
  //- Render the right markup for a given slice type.
  <c:choose>
    <c:when test="slice.getSliceType() == "text">
      <div>${slice.getValue.asHtml(linkResolver)}</div>
    </c:when>
    <c:when test="slice.getSliceType() == "quote">
      <span class='block-quotation'>${slice.getValue()}</span>
    </c:when>
    <c:when test="slice.getSliceType() == "image-with-caption">
      <c:set var="imageWithCaption" value="slice.getValue()"/>
      <p class='block-img'><img src='${imageWithCaption.get("illustration").getUrl()}"></p>
      <span class='image-label'>${imageWithCaption.get("caption").asText()}</span>
    </c:when>
  </c:choose>
</c:forEach>

    
Copy
      @foreach (var slice in prismicdoc.GetSliceZone("blog-post.body").Value) {
  //- Render the right markup for a given slice type.
  @switch (slice.SliceType) {
    case "text": @: <div>@slice.Value.AsHtml(linkResolver)}</div>
    break;
    case "quote": @: <span class='block-quotation'>slice.Value</span>
    break;
    case "image-with-caption": @: 
      <p class='block-img'><img src="@slice.Value.Get("illustration").Url"></p>
      <span class='image-label'>@slice.Value.get("caption").AsText()</span>
}

    
Copy
      <% @doc["blog-post.body"].slices do |slice| %>
  //- Render the right markup for a given slice type.
  <% case slice.slice_type
     when "text" %><div><%= slice.value.as_html(linkResolver) =></div>
  <% when "quote" %><span class='block-quotation'><%= slice.value %></span>
  <% when "image-with-caption" %>
      <p class='block-img'><img src='<%= slice.value["illustration"].url %>"></p>
      <span class='image-label'><%= slice.value["caption"].as_text() %></span>
  <% end %>
<% end %>
    

A more advanced example for integrating landing page slices:

Copy
      mixin featuredItems(slice)
    div.featured-items
        each featuredItem in slice.value.toArray()
            div.col-3.whatcenter
                div.illustration(style='background-image: url(' + featuredItem.get("illustration").url + ');')
                h3 !{featuredItem.get('title') ? featuredItem.get('title').asText() : ''}
                | !{featuredItem.get('summary') ? featuredItem.get('summary').asHtml() : ''}


mixin faq(slice)
    div(class= "faq")
        each faq in slice.value.toArray()
            div(class= slice.label)
                h3 !{faq.get('question') ? faq.get('question').asText() : 'Empty'}
                | !{faq.get('answer') ? faq.get('answer').asHtml() : 'Empty'}


mixin text(slice)
    div(class = "text" + ' #{slice.label? slice.label : ""}')
        | !{slice.value.asHtml()}


head
    title !{page.getText("page.title")}

body.page
    div#page-content
            for slice in page.getSliceZone("page.body").slices
                    case slice.sliceType
                        when 'faq'
                            + faq(slice)
                        when 'featured-items'
                            + featuredItems(slice)
                        when 'text'
                            + text(slice)
    
Copy
      <?php

function featuredItems($slice) {
  global $linkResolver;
  echo "<div class='featured-items'>";
  foreach ($slice->getValue()->getArray() as $featuredItem) {
    echo "<div class='col-3 whatcenter'></div>";
    echo "<div class='illustration'"
         . " style='background-image:url(".$featuredItem->get("illustration")->getUrl().")'>";
    echo "<h3>".($featuredItem->get('title') ? $featuredItem->get('title')->asText() : '')."</h3>";
    echo ($featuredItem->get('summary') ? $featuredItem->get('summary')->asHtml() : '');
  }
  echo "</div>";
}

function faq($slice) {
  global $linkResolver;
  echo "<div class='faq'>";
  foreach ($slice->getValue()->getArray() as $faq) {
    echo "<div class='".$slice->getLabel()."'>"
        . "<h3>".($faq->get('question') ? $faq->get('question')->asText($linkResolver) : '')."</h3>"
        . ($faq->get('question') ? $faq->get('question')->asText($linkResolver) : '')
      . "</div>";
  }
  echo "</div>";
}

function text($slice) {
  global $linkResolver;
  echo "<div class='text ".$slice->getLabel()."'>" . $slice->getValue()->asHtml($linkResolver) . "</div>";
}

?>

<head>
  <title><?= $page->getText('page.title') ?></title>
</head>

<body class="page">
  <div id="page-content">

    <?php 
    foreach($page->getSliceZone("page.body")->getSlices() as $slice) {
         switch($slice->getSliceType()) {
           case 'faq':
             faq($slice);
             break;
           case 'featured-items':
             featuredItems($slice);
             break;
           case 'text':
             text($slice);
         }
    }
    ?>
  </div>
</body>

    
Copy