Example #1
0
def merge(request, layoutTree):
    """Perform grid system merging for the given page.

    Returns None if the page has no layout.
    """
    # Find layout node
    gridSystem = utils.xpath1(utils.gridXPath, layoutTree)
    if gridSystem is None:
        gridSystem = 'deco'
        registry = queryUtility(IRegistry)
        if registry:
            settings = registry.forInterface(IBlocksSettings, check=False)
            gridSystem = settings.default_grid_system or 'deco'

    gridUtil = queryUtility(IGridSystem, gridSystem)
    if gridUtil is None:
        logger.warn('Could not apply grid system "%s"' % gridSystem)
        return layoutTree
    gridUtil = gridUtil()
    for layoutGridNode in utils.gridDataXPath(layoutTree):
        gridinfo = layoutGridNode.attrib['data-grid']
        cssGridClass = gridUtil.transform(gridinfo)
        if cssGridClass is not None:
            if 'class' in layoutGridNode.attrib:
                layoutGridNode.attrib['class'] = layoutGridNode.attrib['class'] + ' ' + cssGridClass  # noqa
            else:
                layoutGridNode.attrib['class'] = cssGridClass
        del layoutGridNode.attrib['data-grid']
    return layoutTree
Example #2
0
    def render(self):
        # Render fields by iterating over the form field tiles, rendering
        # each one, and replacing the tile with the result.
        layout = ILayoutAware(self.context).content
        layoutTree = getHTMLSerializer(layout,
            pretty_print=True, encoding='utf8')
        
        for tileId, tile in self.context.field_tiles(layoutTree.tree):
            # XXX need to include the full Plone view of the field
            widget = self.widgets[tile.id]
            widgetRenderer = getMultiAdapter((widget, self.request), name=u'ploneform-render-widget')
            widgetHtml = widgetRenderer()
            tileTree = html.fromstring(widgetHtml).getroottree()
            tileTarget = xpath1("//*[@id='%s']" % tileId, layoutTree.tree)
            
            if tileTarget is None:
                continue
            
            # clear children, but keep attributes
            oldAttrib = dict(tileTarget.attrib)
            tileTarget.clear()
            tileTarget.attrib.update(oldAttrib)

            # insert tile target with tile body
            tileBody = tileTree.find('body')
            if tileBody is not None:
                tileTarget.text = tileBody.text
                for tileBodyChild in tileBody:
                    tileTarget.append(tileBodyChild)
        
        # TODO:
        # - create form tag
        # - fill in status message
        return str(layoutTree)
Example #3
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
    def transformIterable(self, result, encoding):
        if (
            self.published is None or
            not self.request.get('plone.app.blocks.enabled', False) or
            not isinstance(result, XMLSerializer)
        ):
            return None

        context = aq_parent(aq_base(self.published)) or api.portal.get()
        layout = queryMultiAdapter(
            (context, self.request),
            name='plone_layout'
        )
        root = result.tree.getroot()
        body = root.body

        if layout is None or body is None:
            return result

        body_class = body.attrib.get('class', '')
        body_classes = body_class.split()

        # Get default body classes
        if 'template-' not in body_class and 'site-' not in body_class:
            body_classes.extend([
                n for n in layout.bodyClass(None, self.published).split()
                if n not in body_classes
            ])

        # Get contentLayout body class
        if 'template-layout' in body_classes:
            adapted = ILayoutAware(context, None)
            if adapted is not None:
                layout = getattr(adapted, 'contentLayout', None)
                if layout:
                    # Transform ++contentlayout++default/document.html
                    # into layout-default-document
                    names = LAYOUT_NAME.findall(layout)
                    if len(names) == 1:
                        body_classes.append('layout-' +
                                            names[0].replace('/', '-'))
                else:
                    body_classes.append('layout-custom')

        # Enable mosaic-grid when no grid system is defined
        gridSystem = xpath1(gridXPath, result.tree)
        if gridSystem is None:
            registry = queryUtility(IRegistry)
            if registry:
                settings = registry.forInterface(IBlocksSettings, check=False)
                gridSystem = getattr(
                    settings, 'default_grid_system', None) or None
        if gridSystem is None:
            body_classes.append('mosaic-grid')

        # Set body class
        body.attrib['class'] = ' '.join(body_classes)

        return result
Example #5
0
    def transformIterable(self, result, encoding):
        if self.published is None or \
                not self.request.get('plone.app.blocks.enabled', False) or \
                not isinstance(result, XMLSerializer):
            return None

        context = aq_parent(aq_base(self.published)) or api.portal.get()
        layout = queryMultiAdapter((context, self.request),
                                   name='plone_layout')
        root = result.tree.getroot()
        body = root.find('body')

        if layout is None or body is None:
            return result

        body_class = body.attrib.get('class', '')
        body_classes = body_class.split()

        # Get default body classes
        if 'template-' not in body_class and 'site-' not in body_class:
            body_classes.extend([name for name
                                 in layout.bodyClass(None, self.published)
                                 if name not in body_classes])

        # Get contentLayout body class
        if 'template-layout' in body_classes:
            adapted = ILayoutAware(context, None)
            if adapted is not None:
                layout = getattr(adapted, 'contentLayout', None)
                if layout:
                    # Transform ++contentlayout++default/document.html
                    # into layout-default-document
                    names = LAYOUT_NAME.findall(layout)
                    if len(names) == 1:
                        body_classes.append('layout-' +
                                            names[0].replace('/', '-'))
                else:
                    body_classes.append('layout-custom')

        # Enable mosaic-grid when no grid system is defined
        gridSystem = xpath1(gridXPath, result.tree)
        if gridSystem is None:
            registry = queryUtility(IRegistry)
            if registry:
                settings = registry.forInterface(IBlocksSettings, check=False)
                gridSystem = getattr(
                    settings, 'default_grid_system', None) or None
        if gridSystem is None:
            body_classes.append('mosaic-grid')

        # Set body class
        body.attrib['class'] = ' '.join(body_classes)

        return result
Example #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()
    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
Example #7
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
Example #8
0
def merge(request, layoutTree):
    """Perform grid system merging for the given page.

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

    # Find layout node
    gridSystem = utils.xpath1(utils.gridXPath, layoutTree)
    if gridSystem is None:
        gridSystem = 'deco'

    gridUtil = getUtility(IGridSystem, gridSystem)()
    for layoutGridNode in utils.gridDataXPath(layoutTree):
        gridinfo = layoutGridNode.attrib['data-grid']
        cssGridClass = gridUtil.transform(gridinfo)
        if cssGridClass is not None:
            if 'class' in layoutGridNode.attrib:
                layoutGridNode.attrib['class'] = layoutGridNode.attrib['class'] + ' ' + cssGridClass  # noqa
            else:
                layoutGridNode.attrib['class'] = cssGridClass
        del layoutGridNode.attrib['data-grid']
    return layoutTree
Example #9
0
def merge(request, layoutTree):
    """Perform grid system merging for the given page.

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

    # Find layout node
    gridSystem = utils.xpath1(utils.gridXPath, layoutTree)
    if gridSystem is None:
        gridSystem = 'deco'

    gridUtil = getUtility(IGridSystem, gridSystem)()
    for layoutGridNode in utils.gridDataXPath(layoutTree):
        gridinfo = layoutGridNode.attrib['data-grid']
        cssGridClass = gridUtil.transform(gridinfo)
        if cssGridClass is not None:
            if 'class' in layoutGridNode.attrib:
                layoutGridNode.attrib['class'] = layoutGridNode.attrib[
                    'class'] + ' ' + cssGridClass  # noqa
            else:
                layoutGridNode.attrib['class'] = cssGridClass
        del layoutGridNode.attrib['data-grid']
    return layoutTree
Example #10
0
    def transformIterable(self, result, encoding):
        if self.published is None or \
                not self.request.get('plone.app.blocks.enabled', False) or \
                not isinstance(result, XMLSerializer):
            return None

        context = aq_parent(aq_base(self.published)) or api.portal.get()
        layout = queryMultiAdapter((context, self.request),
                                   name='plone_layout')
        root = result.tree.getroot()
        body = root.find('body')

        if layout and body is not None:
            class_ = layout.bodyClass(None, self.published)
            body.attrib['class'] = ' '.join(
                body.attrib.get('class', '').split() + class_.split())

        gridSystem = xpath1(gridXPath, result.tree)
        if body is not None and gridSystem is None:
            body.attrib['class'] = ' '.join((
                body.attrib.get('class', ' '), 'mosaic-grid'))

        return result
Example #11
0
    def transformIterable(self, result, encoding):
        if self.published is None or \
                not self.request.get('plone.app.blocks.enabled', False) or \
                not isinstance(result, XMLSerializer):
            return None

        context = aq_parent(aq_base(self.published)) or api.portal.get()
        layout = queryMultiAdapter((context, self.request),
                                   name='plone_layout')
        root = result.tree.getroot()
        body = root.find('body')

        if layout and body is not None:
            class_ = layout.bodyClass(None, self.published)
            body.attrib['class'] = ' '.join(
                body.attrib.get('class', '').split() + class_.split())

        gridSystem = xpath1(gridXPath, result.tree)
        if body is not None and gridSystem is None:
            body.attrib['class'] = ' '.join(
                (body.attrib.get('class', ' '), 'mosaic-grid'))

        return result
Example #12
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
Example #13
0
    def render(self):
        # Render fields by iterating over the form field tiles, rendering
        # each one, and replacing the tile with the result.
        layout = ILayoutAware(self.context).content
        layoutTree = getHTMLSerializer(layout,
                                       pretty_print=True,
                                       encoding='utf8')

        for tileId, tile in self.context.field_tiles(layoutTree.tree):
            # XXX need to include the full Plone view of the field
            widget = self.widgets[tile.id]
            widgetRenderer = getMultiAdapter((widget, self.request),
                                             name=u'ploneform-render-widget')
            widgetHtml = widgetRenderer()
            tileTree = html.fromstring(widgetHtml).getroottree()
            tileTarget = xpath1("//*[@id='%s']" % tileId, layoutTree.tree)

            if tileTarget is None:
                continue

            # clear children, but keep attributes
            oldAttrib = dict(tileTarget.attrib)
            tileTarget.clear()
            tileTarget.attrib.update(oldAttrib)

            # insert tile target with tile body
            tileBody = tileTree.find('body')
            if tileBody is not None:
                tileTarget.text = tileBody.text
                for tileBodyChild in tileBody:
                    tileTarget.append(tileBodyChild)

        # TODO:
        # - create form tag
        # - fill in status message
        return str(layoutTree)