Ejemplo n.º 1
0
def merge(request, pageTree, removePanelLinks=False, removeLayoutLink=True):
    """Perform panel merging for the given page.

    Returns None if the page has no layout.
    """

    # Find layout node
    layoutHref = utils.xpath1(utils.layoutXPath, pageTree)
    if layoutHref is None:
        return None

    # Resolve layout tree
    baseURL = request.getURL()
    if request.getVirtualRoot():
        # plone.subrequest deals with VHM requests
        baseURL = ''
    layoutHref = parse.urljoin(baseURL, layoutHref)  # noqa: turn the link absolute
    # Pass special ajax_load parameter forward to allow layout indirection
    # views to select, for example, default AJAX layout instead of full layout.
    if request.form.get('ajax_load'):
        parts = list(parse.urlparse(layoutHref))
        query = parse.parse_qs(parts[4])
        query['ajax_load'] = request.form.get('ajax_load')
        parts[4] = parse.urlencode(query)
        layoutHref = parse.urlunparse(parts)
    layoutTree = utils.resolve(layoutHref)
    if layoutTree is None:
        return None

    # Map page panels onto the layout

    pagePanels = dict(
        (node.attrib['data-panel'], node)
        for node in utils.panelXPath(pageTree)
    )

    layoutPanels = dict(
        (node.attrib['data-panel'], node)
        for node in utils.panelXPath(layoutTree)
    )

    # Site layout should always have element with data-panel="content"
    # Note: This could be more generic, but that would empower editors too much
    if 'content' in pagePanels and 'content' not in layoutPanels:
        for node in layoutTree.xpath('//*[@id="content"]'):
            node.attrib['data-panel'] = 'content'
            layoutPanels['content'] = node
            break

    for panelId, layoutPanelNode in layoutPanels.items():
        pagePanelNode = pagePanels.get(panelId, None)
        if pagePanelNode is not None:
            utils.replace_content(layoutPanelNode, pagePanelNode)
        if removePanelLinks:
            del layoutPanelNode.attrib['data-panel']

    if removeLayoutLink:
        del pageTree.getroot().attrib[utils.layoutAttrib]

    return layoutTree
Ejemplo n.º 2
0
def merge(request, pageTree, removePanelLinks=False, removeLayoutLink=True):
    """Perform panel merging for the given page.

    Returns None if the page has no layout.
    """

    # Find layout node
    layoutHref = utils.xpath1(utils.layoutXPath, pageTree)
    if layoutHref is None:
        return None

    # Resolve layout tree
    baseURL = request.getURL()
    if request.getVirtualRoot():
        # plone.subrequest deals with VHM requests
        baseURL = ''
    layoutHref = urljoin(baseURL, layoutHref)  # turn the link absolute
    if request.form.get('ajax_load'):
        parts = list(urlparse(layoutHref))
        query = parse_qs(parts[4])
        query['ajax_load'] = request.form.get('ajax_load')
        parts[4] = urlencode(query)
        layoutHref = urlunparse(parts)
    layoutTree = utils.resolve(layoutHref)
    if layoutTree is None:
        return None

    # Map page panels onto the layout

    pagePanels = dict((node.attrib['data-panel'], node)
                      for node in utils.panelXPath(pageTree))

    layoutPanels = dict((node.attrib['data-panel'], node)
                        for node in utils.panelXPath(layoutTree))

    # Site layout should always have element with data-panel="content"
    # Note: This could be more generic, but that would empower editors too much
    if 'content' in pagePanels and 'content' not in layoutPanels:
        for node in layoutTree.xpath('//*[@id="content"]'):
            node.attrib['data-panel'] = 'content'
            layoutPanels['content'] = node
            break

    for panelId, layoutPanelNode in layoutPanels.items():
        pagePanelNode = pagePanels.get(panelId, None)
        if pagePanelNode is not None:
            utils.replace_content(layoutPanelNode, pagePanelNode)
        if removePanelLinks:
            del layoutPanelNode.attrib['data-panel']

    if removeLayoutLink:
        del pageTree.getroot().attrib[utils.layoutAttrib]

    return layoutTree
Ejemplo n.º 3
0
def cook_layout(layout):
    """Return main_template compatible layout"""
    result = getHTMLSerializer(layout, encoding='utf-8')
    nsmap = {'metal': 'http://namespaces.zope.org/metal'}

    # wrap all panels with a metal:fill-slot -tag
    for layoutPanelNode in panelXPath(result.tree):
        panelId = layoutPanelNode.attrib['data-panel']
        slot = etree.Element('{%s}%s' % (nsmap['metal'], panelId), nsmap=nsmap)
        slot.attrib['define-slot'] = panelId
        slot_parent = layoutPanelNode.getparent()
        slot_parent_index = slot_parent.index(layoutPanelNode)
        slot.append(layoutPanelNode)
        slot_parent.insert(slot_parent_index, slot)

    root = result.tree.getroot()
    root.attrib['tal:define'] = """\
portal_state python:context.restrictedTraverse('@@plone_portal_state');
context_state python:context.restrictedTraverse('@@plone_context_state');
plone_view python:context.restrictedTraverse('@@plone');
lang portal_state/language;
view nocall:view | nocall: plone_view;
dummy python: plone_view.mark_view(view);
portal_url portal_state/portal_url;
checkPermission nocall: context/portal_membership/checkPermission;
site_properties nocall:context/portal_properties/site_properties;
ajax_load request/ajax_load | nothing;
ajax_include_head request/ajax_include_head | nothing;
dummy python:request.RESPONSE.setHeader('X-UA-Compatible', 'IE=edge,chrome=1');
dummy python:options.update({'state': options.get('state', request.get('controller_state'))});
"""

    template = '<metal:page define-macro="master">\n%s\n</metal:page>'
    metal = 'xmlns:metal="http://namespaces.zope.org/metal"'
    return (template % ''.join(result)).replace(metal, '')
Ejemplo n.º 4
0
 def item_panels(self):
     default_view = self.default_view
     html = default_view()
     if isinstance(html, six.text_type):
         html = html.encode('utf-8')
     serializer = getHTMLSerializer([html],
                                    pretty_print=False,
                                    encoding='utf-8')
     panels = dict((node.attrib['data-panel'], node)
                   for node in utils.panelXPath(serializer.tree))
     if panels:
         request = self.request.clone()
         request.URL = self.content_context.absolute_url() + '/'
         try:
             renderTiles(request, serializer.tree)
         except RuntimeError:  # maximum recursion depth exceeded
             return []
         clear = '<div style="clear: both;"></div>'
         return [
             ''.join([
                 serializer.serializer(child)
                 for child in node.getchildren()
             ]) for name, node in panels.items()
         ] + [clear]
     return []
Ejemplo n.º 5
0
def merge(request, pageTree, removePanelLinks=False, removeLayoutLink=True):
    """Perform panel merging for the given page.

    Returns None if the page has no layout.
    """

    # Find layout node
    layoutHref = utils.xpath1(utils.layoutXPath, pageTree)
    if layoutHref is None:
        return None

    # Resolve layout tree
    baseURL = request.getURL()
    if request.getVirtualRoot():
        # plone.subrequest deals with VHM requests
        baseURL = ''
    layoutHref = urljoin(baseURL, layoutHref)  # turn the link absolute
    layoutTree = utils.resolve(layoutHref)
    if layoutTree is None:
        return None

    # Map page panels onto the layout

    pagePanels = dict(
        (node.attrib['data-panel'], node)
        for node in utils.panelXPath(pageTree)
    )

    for layoutPanelNode in utils.panelXPath(layoutTree):
        panelId = layoutPanelNode.attrib['data-panel']
        pagePanelNode = pagePanels.get(panelId, None)
        if pagePanelNode is not None:
            utils.replace_content(layoutPanelNode, pagePanelNode)
        if removePanelLinks:
            del layoutPanelNode.attrib['data-panel']

    if removeLayoutLink:
        del pageTree.getroot().attrib[utils.layoutAttrib]

    return layoutTree
Ejemplo n.º 6
0
def merge(request, pageTree, removePanelLinks=False, removeLayoutLink=True):
    """Perform panel merging for the given page.

    Returns None if the page has no layout.
    """

    # Find layout node
    layoutHref = utils.xpath1(utils.layoutXPath, pageTree)
    if layoutHref is None:
        return None

    # Resolve layout tree
    baseURL = request.getURL()
    layoutHref = urljoin(baseURL, layoutHref)  # turn the link absolute
    layoutTree = utils.resolve(layoutHref)
    if layoutTree is None:
        return None

    # Map page panels onto the layout

    pagePanels = dict(
        (node.attrib['data-panel'], node)
        for node in utils.panelXPath(pageTree)
        )

    for layoutPanelNode in utils.panelXPath(layoutTree):
        panelId = layoutPanelNode.attrib['data-panel']
        pagePanelNode = pagePanels.get(panelId, None)
        if pagePanelNode is not None:
            utils.replace_content(layoutPanelNode, pagePanelNode)
        if removePanelLinks:
            del layoutPanelNode.attrib['data-panel']

    if removeLayoutLink:
        del pageTree.getroot().attrib[utils.layoutAttrib]

    return layoutTree
Ejemplo n.º 7
0
    def tiles_instances(self):
        tiles = {}
        baseURL = self.request.getURL()
        tree = lxml.html.fromstring(self.content)

        for panelNode in utils.panelXPath(tree):
            panelName = panelNode.attrib['data-panel']

            for tileNode in utils.bodyTileXPath(panelNode):
                tileName = tileNode.attrib['data-tile']

                tileTree = utils.resolve(urljoin(baseURL, tileName))
                tile = tileTree.find('body')

                if panelName not in tiles.keys():
                    tiles[panelName] = {}

                tiles[panelName][tileName] = (tile.text or '') + \
                    ''.join([lxml.html.tostring(child) for child in tile])

        return json.dumps(tiles)
Ejemplo n.º 8
0
 def item_panels(self):
     default_view = self.default_view
     html = default_view()
     if isinstance(html, unicode):
         html = html.encode('utf-8')
     serializer = getHTMLSerializer([html], pretty_print=False,
                                    encoding='utf-8')
     panels = dict(
         (node.attrib['data-panel'], node)
         for node in utils.panelXPath(serializer.tree)
     )
     if panels:
         request = self.request.clone()
         request.URL = self.content_context.absolute_url() + '/'
         try:
             renderTiles(request, serializer.tree)
         except RuntimeError:  # maximum recursion depth exceeded
             return []
         clear = '<div style="clear: both;"></div>'
         return [''.join([serializer.serializer(child)
                          for child in node.getchildren()])
                 for name, node in panels.items()] + [clear]
     return []