diff --git a/prismic/fragments.py b/prismic/fragments.py
index 14e0a7a..907e956 100644
--- a/prismic/fragments.py
+++ b/prismic/fragments.py
@@ -178,8 +178,24 @@ def as_html(self, link_resolver):
html.append("""""" % key)
html.append(self.fragment_to_html(fragment, link_resolver))
html.append("""""")
+
return ''.join(html)
+ def __getitem__(self, name):
+ return self.fragments[name]
+
+ def __iter__(self):
+ return iter(self.fragments)
+
+ def keys(self):
+ return self.fragments.keys()
+
+ def items(self):
+ return self.fragments.items()
+
+ def values(self):
+ return self.fragments.values()
+
# Links
class Link(FragmentElement):
@@ -224,13 +240,21 @@ def __init__(self, value):
def as_html(self, documentlink_resolver, html_serializer=None):
"""Get the DocumentLink as html.
- :param documentlink_resolver: A resolver function will be called with :class:`prismic.fragments.Fragment.DocumentLink ` object as argument. Resolver function should return a string, the local url to the document.
+ :param documentlink_resolver: A resolver function will be called with
+ :class:`prismic.fragments.Fragment.DocumentLink ` object as
+ argument. Resolver function should return a string, the local url to the document.
"""
- return """%(slug)s""" % {"link": self.get_url(documentlink_resolver), "slug": self.slug}
+ return """%(slug)s""" % {
+ "link": self.get_url(documentlink_resolver),
+ "slug": self.slug
+ }
def get_url(self, documentlink_resolver=None):
if not hasattr(documentlink_resolver, '__call__'):
- raise Exception("documentlink_resolver should be a callable object, but it's: %s" % type(documentlink_resolver))
+ raise Exception(
+ "documentlink_resolver should be a callable object, but it's: %s"
+ % type(documentlink_resolver)
+ )
return documentlink_resolver(self)
def get_document_id(self):
@@ -468,6 +492,8 @@ def as_html(self, link_resolver):
html.append(group_doc.as_html(link_resolver))
return "\n".join(html)
+ def __iter__(self):
+ return iter(self.value)
class Slice(FragmentElement):
@@ -486,6 +512,48 @@ def as_html(self, link_resolver):
"body": self.value.as_html(link_resolver)
}
+ class CompositeSlice(FragmentElement):
+
+ def __init__(self, slice_type, slice_label, elt):
+ self.slice_type = slice_type
+ self.slice_label = slice_label
+ self.repeat = []
+ self.non_repeat = {}
+
+ _repeat = elt.get('repeat')
+ _non_repeat = elt.get('non-repeat')
+
+ if any(_repeat):
+ self.repeat = self.parse_repeat(_repeat)
+
+ if _non_repeat:
+ self.non_repeat = self.parse_non_repeat(_non_repeat)
+
+ @staticmethod
+ def parse_repeat(repeat):
+ return Fragment.Group(repeat)
+
+ @staticmethod
+ def parse_non_repeat(non_repeat):
+ return Fragment.Group([non_repeat])
+
+ def as_html(self, link_resolver):
+ classes = ['slice']
+ if self.slice_label:
+ classes.append(self.slice_label)
+
+ body = ""
+ if self.non_repeat:
+ body += self.non_repeat.as_html(link_resolver)
+
+ if self.repeat:
+ body += self.repeat.as_html(link_resolver)
+
+ return '%(body)s
' % {
+ "slice_type": self.slice_type,
+ "classes": ' '.join(classes),
+ "body": body
+ }
class SliceZone(FragmentElement):
@@ -494,8 +562,14 @@ def __init__(self, value):
for elt in value:
slice_type = elt['slice_type']
slice_label = elt.get('slice_label')
- fragment = Fragment.from_json(elt['value'])
- self.slices.append(Fragment.Slice(slice_type, slice_label, fragment))
+
+ # Old style slice
+ if 'value' in elt:
+ fragment = Fragment.from_json(elt['value'])
+ self.slices.append(Fragment.Slice(slice_type, slice_label, fragment))
+ else:
+ Fragment.CompositeSlice(slice_type, slice_label, elt)
+ self.slices.append(Fragment.CompositeSlice(slice_type, slice_label, elt))
def as_html(self, link_resolver):
html = []
@@ -503,6 +577,9 @@ def as_html(self, link_resolver):
html.append(slice.as_html(link_resolver))
return "\n".join(html)
+ def __iter__(self):
+ return iter(self.slices)
+
class StructuredText(object):
diff --git a/setup.py b/setup.py
index 70cdcba..026c29d 100644
--- a/setup.py
+++ b/setup.py
@@ -8,7 +8,7 @@
setup(
name='prismic',
- version='1.4.2',
+ version='1.5.0',
description='Prismic.io development kit',
author='The Prismic.io Team',
author_email='contact@prismic.io',
diff --git a/tests/test_prismic.py b/tests/test_prismic.py
index 6dffd67..6cfdc0d 100644
--- a/tests/test_prismic.py
+++ b/tests/test_prismic.py
@@ -9,7 +9,7 @@
from prismic.exceptions import InvalidTokenError, AuthorizationNeededError, InvalidURLError
from .test_prismic_fixtures import fixture_api, fixture_search, fixture_groups, \
fixture_structured_lists, fixture_empty_paragraph, fixture_store_geopoint, fixture_image_links, \
- fixture_spans_labels, fixture_block_labels, fixture_custom_html, fixture_slices
+ fixture_spans_labels, fixture_block_labels, fixture_custom_html, fixture_slices, fixture_composite_slices
import time
import json
import logging
@@ -37,6 +37,7 @@ def setUp(self):
self.fixture_spans_labels = json.loads(fixture_spans_labels)
self.fixture_custom_html = json.loads(fixture_custom_html)
self.fixture_slices = json.loads(fixture_slices)
+ self.fixture_composite_slices = json.loads(fixture_composite_slices)
self.api = prismic.Api(self.fixture_api, self.token, ShelveCache("prismictest"), None)
@@ -409,7 +410,7 @@ def test_slicezone(self):
self.maxDiff = 10000
doc = prismic.Document(self.fixture_slices)
slices = doc.get_slice_zone("article.blocks")
- slices_html =slices.as_html(PrismicTestCase.link_resolver)
+ slices_html = slices.as_html(PrismicTestCase.link_resolver)
expected_html = (
"""\n"""
@@ -417,6 +418,17 @@ def test_slicezone(self):
# Comparing len rather than actual strings because json loading is not in a deterministic order for now
self.assertEqual(len(expected_html), len(slices_html))
+ def test_composite_slices(self):
+ self.maxDiff = 1000
+ doc = prismic.Document(self.fixture_composite_slices)
+ slices = doc.get_slice_zone("test.body")
+ slices_html = slices.as_html(PrismicTestCase.link_resolver)
+ expected_html = """
+"""
+ # Comparing len rather than actual strings because json loading is not in a deterministic order for now
+ self.assertEqual(len(expected_html), len(slices_html))
+
def test_image_links(self):
self.maxDiff = 10000
text = prismic.fragments.StructuredText(self.fixture_image_links.get('value'))
@@ -516,6 +528,7 @@ def test_geopoint_near(self):
.query(predicates.near('my.store.coordinates', 40.689757, -74.0451453, 15))
self.assertEqual(f.data['q'], ['[[:d = geopoint.near(my.store.coordinates, 40.689757, -74.0451453, 15)]]'])
+
class TestCache(unittest.TestCase):
def setUp(self):
diff --git a/tests/test_prismic_fixtures.py b/tests/test_prismic_fixtures.py
index 6523edd..09c54f3 100644
--- a/tests/test_prismic_fixtures.py
+++ b/tests/test_prismic_fixtures.py
@@ -1246,3 +1246,138 @@
}
}
"""
+
+fixture_composite_slices = """
+{
+ "alternate_languages": [],
+ "data": {
+ "test": {
+ "body": {
+ "type": "SliceZone",
+ "value": [
+ {
+ "non-repeat": {
+ "non-repeat-text": {
+ "type": "StructuredText",
+ "value": [
+ {
+ "spans": [],
+ "text": "Slice A non-repeat text",
+ "type": "paragraph"
+ }
+ ]
+ },
+ "non-repeat-title": {
+ "type": "StructuredText",
+ "value": [
+ {
+ "spans": [],
+ "text": "Slice A non-repeat title",
+ "type": "heading1"
+ }
+ ]
+ }
+ },
+ "repeat": [
+ {
+ "repeat-text": {
+ "type": "StructuredText",
+ "value": [
+ {
+ "spans": [],
+ "text": "Repeatable text A",
+ "type": "paragraph"
+ }
+ ]
+ },
+ "repeat-title": {
+ "type": "StructuredText",
+ "value": [
+ {
+ "spans": [],
+ "text": "Repeatable title A",
+ "type": "heading1"
+ }
+ ]
+ }
+ },
+ {
+ "repeat-text": {
+ "type": "StructuredText",
+ "value": [
+ {
+ "spans": [],
+ "text": "Repeatable text B",
+ "type": "paragraph"
+ }
+ ]
+ },
+ "repeat-title": {
+ "type": "StructuredText",
+ "value": [
+ {
+ "spans": [],
+ "text": "Repeatable title B",
+ "type": "heading1"
+ }
+ ]
+ }
+ }
+ ],
+ "slice_label": null,
+ "slice_type": "slice-a",
+ "type": "Slice"
+ },
+ {
+ "non-repeat": {
+ "image": {
+ "type": "Image",
+ "value": {
+ "main": {
+ "alt": null,
+ "copyright": null,
+ "dimensions": {
+ "height": 500,
+ "width": 800
+ },
+ "url": "https://prismic-io.s3.amazonaws.com/tails/014c1fe46e3ceaf04b7cc925b2ea7e8027dc607a_mobile_header_tp.png"
+ },
+ "views": {}
+ }
+ },
+ "title": {
+ "type": "StructuredText",
+ "value": [
+ {
+ "spans": [],
+ "text": "Slice A non-repeat title",
+ "type": "heading1"
+ }
+ ]
+ }
+ },
+ "repeat": [
+ {}
+ ],
+ "slice_label": null,
+ "slice_type": "slice-b",
+ "type": "Slice"
+ }
+ ]
+ }
+ }
+ },
+ "first_publication_date": "2017-10-10T11:30:08+0000",
+ "href": "http://tails.prismic.io/api/v1/documents/search?ref=WdyvQCsAAOgSj_r0&q=%5B%5B%3Ad+%3D+at%28document.id%2C+%22WdyvPCsAAOMSj_rf%22%29+%5D%5D",
+ "id": "WdyvPCsAAOMSj_rf",
+ "lang": "en-gb",
+ "last_publication_date": "2017-10-10T11:30:08+0000",
+ "linked_documents": [],
+ "slugs": [
+ "slice-a-non-repeat-title"
+ ],
+ "tags": [],
+ "type": "test",
+ "uid": "test"
+}
+"""
\ No newline at end of file