Skip to content

Commit

Permalink
All helpers from Document now available within a Group
Browse files Browse the repository at this point in the history
  • Loading branch information
erwan committed Oct 30, 2014
1 parent aa743e2 commit ea9e64b
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 107 deletions.
93 changes: 2 additions & 91 deletions prismic/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,11 +324,11 @@ def get_tags(self):
return self._data.get("tags")


class Document(object):
class Document(Fragment.WithFragments):

def __init__(self, data):
Fragment.WithFragments.__init__(self, {})
self._data = data
self.fragments = {}
self.linked_documents = []

fragments = data.get("data").get(self.type) if "data" in data else {}
Expand All @@ -353,94 +353,5 @@ def __getattr__(self, name):
def slug(self):
return self.slugs[0] if self.slugs else "-"

def get_field(self, field):
return self.fragments.get(field)

def get_all(self, field):
indexed_key = "^%s(\[\d+\])?$" % field
return list(v for k, v in list(self.fragments.items()) if re.match(indexed_key, k))

def get_fragment_type(self, field, f_type):
fragment = self.fragments.get(field)
return fragment if isinstance(fragment, f_type) else None

def get_image(self, field, view="main"):
fragment = self.get_field(field)
if isinstance(fragment, Fragment.Image):
return fragment.get_view(view) if fragment else None
if view == "main" and isinstance(fragment, StructuredText):
image = fragment.get_image()
return image.view if image else None
return None

def get_number(self, field):
return self.get_fragment_type(field, Fragment.Number)

def get_color(self, field):
return self.get_fragment_type(field, Fragment.Color)

def get_text(self, field):
fragment = self.fragments.get(field)
if isinstance(fragment, StructuredText):
texts = [block.text for block in fragment.blocks if isinstance(
block, fragment.Text)]
return "\n".join(texts) if texts else None
elif fragment is None:
return None
else:
return fragment.value

def get_link(self, field):
return self.get_fragment_type(field, Fragment.Link)

def get_embed(self, field):
return self.get_fragment_type(field, Fragment.Embed)

def get_date(self, field):
return self.get_fragment_type(field, Fragment.Date)

def get_timestamp(self, field):
return self.get_fragment_type(field, Fragment.Timestamp)

def get_geopoint(self, field):
return self.get_fragment_type(field, Fragment.GeoPoint)

def get_group(self, field):
return self.get_fragment_type(field, Fragment.Group)

def get_structured_text(self, field):
return self.get_fragment_type(field, StructuredText)

def get_html(self, field, link_resolver):
"""Get the html of a field.
:param field: String with a name of the field to get.
:param link_resolver: A resolver function for document links.
Will be called with :class:`prismic.fragments.Fragment.DocumentLink <prismic.fragments.Fragment.DocumentLink>`
object as argument. Resolver function should return a string, the local url to the document.
"""
fragment = self.fragments.get(field)
return self.fragment_to_html(fragment, link_resolver)

@staticmethod
def fragment_to_html(fragment, link_resolver, html_serializer=None):
if isinstance(fragment, StructuredText):
return fragment.as_html(link_resolver, html_serializer)
if isinstance(fragment, Fragment.DocumentLink)\
or isinstance(fragment, Fragment.Image)\
or isinstance(fragment, Fragment.Image.View):
return fragment.as_html(link_resolver)
elif fragment:
return fragment.as_html
return None

def as_html(self, link_resolver):
html = []
for key, fragment in list(self.fragments.items()):
html.append("""<section data-field="%s">""" % key)
html.append(self.fragment_to_html(fragment, link_resolver))
html.append("""</section>""")
return ''.join(html)

def __repr__(self):
return "Document %s" % self.fragments
113 changes: 101 additions & 12 deletions prismic/fragments.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,103 @@ def from_json(cls, data):

log.warning("fragment_type not found: %s" % fragment_type)

class WithFragments(object):

def __init__(self, fragments):
self.fragments = fragments

def get(self, field):
return self.fragments.get(field, None)

def get_field(self, field):
return self.fragments.get(field, None)

def get_all(self, field):
indexed_key = "^%s(\[\d+\])?$" % field
return list(v for k, v in list(self.fragments.items()) if re.match(indexed_key, k))

def get_fragment_type(self, field, f_type):
fragment = self.fragments.get(field)
return fragment if isinstance(fragment, f_type) else None

def get_image(self, field, view="main"):
fragment = self.get_field(field)
if isinstance(fragment, Fragment.Image):
return fragment.get_view(view) if fragment else None
if view == "main" and isinstance(fragment, StructuredText):
image = fragment.get_image()
return image.view if image else None
return None

def get_number(self, field):
return self.get_fragment_type(field, Fragment.Number)

def get_color(self, field):
return self.get_fragment_type(field, Fragment.Color)

def get_text(self, field):
fragment = self.fragments.get(field)
if isinstance(fragment, StructuredText):
texts = [block.text for block in fragment.blocks if isinstance(
block, fragment.Text)]
return "\n".join(texts) if texts else None
elif fragment is None:
return None
else:
return fragment.value

def get_link(self, field):
return self.get_fragment_type(field, Fragment.Link)

def get_embed(self, field):
return self.get_fragment_type(field, Fragment.Embed)

def get_date(self, field):
return self.get_fragment_type(field, Fragment.Date)

def get_timestamp(self, field):
return self.get_fragment_type(field, Fragment.Timestamp)

def get_geopoint(self, field):
return self.get_fragment_type(field, Fragment.GeoPoint)

def get_group(self, field):
return self.get_fragment_type(field, Fragment.Group)

def get_structured_text(self, field):
return self.get_fragment_type(field, StructuredText)

def get_html(self, field, link_resolver):
"""Get the html of a field.
:param field: String with a name of the field to get.
:param link_resolver: A resolver function for document links.
Will be called with :class:`prismic.fragments.Fragment.DocumentLink <prismic.fragments.Fragment.DocumentLink>`
object as argument. Resolver function should return a string, the local url to the document.
"""
fragment = self.fragments.get(field)
return self.fragment_to_html(fragment, link_resolver)

@staticmethod
def fragment_to_html(fragment, link_resolver, html_serializer=None):
if isinstance(fragment, StructuredText):
return fragment.as_html(link_resolver, html_serializer)
if isinstance(fragment, Fragment.DocumentLink)\
or isinstance(fragment, Fragment.Image)\
or isinstance(fragment, Fragment.Image.View):
return fragment.as_html(link_resolver)
elif fragment:
return fragment.as_html
return None

def as_html(self, link_resolver):
html = []
for key, fragment in list(self.fragments.items()):
html.append("""<section data-field="%s">""" % key)
html.append(self.fragment_to_html(fragment, link_resolver))
html.append("""</section>""")
return ''.join(html)

# Links

class Link(FragmentElement):
Expand Down Expand Up @@ -276,22 +373,14 @@ def as_html(self):
return """<time>%s</time>""" % self.value

class Group(BasicFragment):

def __init__(self, value):
self.value = []
for elt in value:
group = {}
fragments = {}
for name, frag in elt.items():
group[name] = Fragment.from_json(frag)
self.value.append(group)

@property
def as_html(self):
result = ""
for element in self.value:
for k, v in element.items():
result += ("<section data-field=\"%(key)s\">%(html)s</section" %
{"key": k, "html": v.as_html})
return result
fragments[name] = Fragment.from_json(frag)
self.value.append(Fragment.WithFragments(fragments))


class StructuredText(object):
Expand Down
22 changes: 18 additions & 4 deletions tests/test_doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,21 @@ def test_get_number(self):
# endgist
self.assertEqual(price, 2.5)

def test_images(self):
api = prismic.get('https://lesbonneschoses.prismic.io/api')
response = api.form('everything').query(predicates.at("document.id", "UlfoxUnM0wkXYXbO")) \
.ref(api.get_master()).submit()
doc = response.documents[0]
# startgist:360d054f79680bd48679:prismic-images.py
# Accessing image fields
image = doc.get_image('product.image')
# By default the 'main' view is returned
url = image.url
# endgist
self.assertEqual(
url,
'https://prismic-io.s3.amazonaws.com/lesbonneschoses/f606ad513fcc2a73b909817119b84d6fd0d61a6d.png')

def test_date_timestamp(self):
api = prismic.get('https://lesbonneschoses.prismic.io/api')
response = api.form('everything').query(predicates.at("document.id", "UlfoxUnM0wkXYXbl"))\
Expand Down Expand Up @@ -211,11 +226,10 @@ def resolver(document_link):
group = document.get_group("article.documents")
docs = (group and group.value) or []
for doc in docs:
# Desc and Link are Fragments, their type depending on what's declared in the Document Mask
desc = doc.get("desc", None)
link = doc.get("linktodoc", None)
desc = doc.get_structured_text("desc")
link = doc.get_link("linktodoc")
# endgist
self.assertEqual(docs[0]["desc"].as_html(resolver), "<p>A detailed step by step point of view on how installing happens.</p>")
self.assertEqual(docs[0].get_structured_text("desc").as_html(resolver), "<p>A detailed step by step point of view on how installing happens.</p>")

def test_link(self):
data = "{\"id\":\"abcd\",\"type\":\"article\",\"href\":\"\",\"slugs\":[],\"tags\":[],\"data\":{\"article\":{\"source\":{\"type\":\"Link.document\",\"value\":{\"document\":{\"id\":\"UlfoxUnM0wkXYXbE\",\"type\":\"product\",\"tags\":[\"Macaron\"],\"slug\":\"dark-chocolate-macaron\"},\"isBroken\":false}}}}}"
Expand Down

0 comments on commit ea9e64b

Please sign in to comment.