def parse_links(html, request_path=None, encoding=None):
    """Process all links in given html and replace them if markup is added."""
    if encoding is None:
        encoding = settings.DEFAULT_CHARSET

    # The passed HTML may be a string or bytes, depending on what is calling
    # this method. For example, Django response.content is always bytes. We
    # always want this content to be a string for our purposes.
    html_as_text = force_str(html, encoding=encoding)

    # This call invokes Wagtail-specific logic that converts references to
    # Wagtail pages, documents, and images to their proper link URLs.
    expanded_html = expand_db_html(html_as_text)

    # Parse links only in the <body> of the HTML
    body_html = get_body_html(expanded_html)
    if body_html is None:
        return expanded_html

    link_tags = get_link_tags(body_html)
    for tag in link_tags:
        tag_with_markup = add_link_markup(tag, request_path)
        if tag_with_markup:
            expanded_html = expanded_html.replace(tag, tag_with_markup)

    return expanded_html
示例#2
0
文件: rich_text.py 项目: bi-sdal/cln
 def render(self, name, value, attrs=None):
     if value is None:
         translated_value = None
     else:
         translated_value = expand_db_html(value)  #, for_editor=True)
     return super(TinyMCERichTextArea, self).render(name, translated_value,
                                                    attrs)
示例#3
0
    def get_html(news_stories, additional_link_params, header_html, extra_html,
                 footer_html):
        html = "<html><head></head><body>" + header_html
        html = html + "<ul>"
        for news_story in news_stories.order_by('-story_date'):
            url = 'https://loop.lib.uchicago.edu' + news_story.url_path.replace(
                '/loop', '',
                1) + '?' + urllib.parse.urlencode(additional_link_params)
            html = html + "<li><a href='" + url + "'>"
            html = html + news_story.title
            html = html + "</a></li>"
        html = html + "</ul>"
        html = html + extra_html
        html = html + footer_html
        html = html + "</body></html>"

        # rough pass to clean strangely nested elements.
        soup = BeautifulSoup(html, "lxml")

        # do more cleanup work.
        html = clean_html(str(soup))

        # get the real links for things like documents and internal pages.
        html = expand_db_html(html)

        return html
示例#4
0
def richtext_force_external_links(value):
    """Filter to force all href["target"] attributes to be blank
    This is similar to the core richtext filter
    https://github.com/wagtail/wagtail/blob/main/wagtail/core/templatetags/wagtailcore_tags.py#L97-L108

    The main difference being we want to force all links to open in a new window, this is useful for front end
    form elements where the user would risk losing any form data. Typical scenario is getting the the end of
    a form, clicking a link to view "terms and conditions", then upon returning to the form page the form inputs
    could be reset.

    We still set html via `expand_db_html`, to take care of any processing that may be added already, or in the future.
    """
    if isinstance(value, RichText):
        # passing a RichText value through the |richtext_force_external_links filter should have no effect
        return value
    elif value is None:
        html = ""
    else:
        if not isinstance(value, str):
            raise TypeError(
                "'richtext' template filter received an invalid value; expected string, got {}.".format(
                    type(value)
                )
            )
        html = expand_db_html(value)
        soup = BeautifulSoup(html, "html.parser")
        links = soup.find_all("a")
        for link in links:
            link["target"] = "_blank"
        html = str(soup)
    return render_to_string("wagtailcore/shared/richtext.html", {"html": html})
示例#5
0
    def test_expand_db_html_with_embed(self, get_embed):
        from wagtail.embeds.models import Embed

        get_embed.return_value = Embed(html="test html")
        html = '<embed embedtype="media" url="http://www.youtube.com/watch" />'
        result = expand_db_html(html)
        self.assertIn("test html", result)
def richtext(value):
    if value is not None:
        html = expand_db_html(value)
    else:
        html = ''

    return mark_safe(html)
示例#7
0
def rich_text(value):
    if isinstance(value, RichText):
        # passing a RichText value through the |richtext filter should have no effect
        return str(value)
    elif value is None:
        html = ''
    else:
        html = expand_db_html(value)

    return mark_safe(html)
def richtext(value):
    if isinstance(value, RichText):
        # passing a RichText value through the |richtext filter should have no effect
        return value
    elif value is None:
        html = ''
    else:
        html = expand_db_html(value)

    return mark_safe('<div class="rich-text">' + html + '</div>')
示例#9
0
def richtext(value):
    if isinstance(value, RichText):
        # passing a RichText value through the |richtext filter should have no effect
        return value
    elif value is None:
        html = ''
    else:
        html = expand_db_html(value)

    return mark_safe('<div class="rich-text">' + html + '</div>')
示例#10
0
def richtext_unwrapped(value):
    # if isinstance(value, RichText):
    #     return value
    if value is None:
        html = ""
    else:
        html = expand_db_html(value)

    if html.startswith("<p>") and html.endswith("</p>"):
        html = html[3:-4]
    return mark_safe(html)
示例#11
0
def simplerichtext(value):
    """
    Simple richtext filter to avoid the wrapping <div class='richtext'></div> markup
    """
    if isinstance(value, SimpleRichText):
        html = value
    elif value is None:
        html = ''
    else:
        html = expand_db_html(value)

    return mark_safe(html)
示例#12
0
def inlinerichtext(value):
    if value is None:
        html = ''
    else:
        if isinstance(value, str):
            html = expand_db_html(value)
        else:
            raise TypeError(
                "'richtext' template filter received an invalid value; expected string, got {}.".format(type(value)))
    html = html.replace('<p>', '')
    html = html.replace('</p>', '')
    return mark_safe(html)
    def render(self, name, value, attrs=None):
        if value is None:
            translated_value = None
        else:
            # if WAGTAIL_VERSION >= '2.0':
            #     translated_value = self.converter.from_database_format(value, for_editor=True)
            # else:
            #     print(self.converter)

            translated_value = expand_db_html(value)
        return super(TinyMCERichTextArea, self).render(name, translated_value,
                                                       attrs)
class ServicesPage(Page):
    subpage_types = []   
    max_count = 1 
    # Replace wrapped rich-text div
    RichText.__html__ = lambda self: expand_db_html(self.source)
    
    content_panels = Page.content_panels + [
        MultiFieldPanel(
            [InlinePanel("services_list", label="Service"), ],
            heading="Services",
        )
    ]
def richtext(value):
    if isinstance(value, RichText):
        # passing a RichText value through the |richtext filter should have no effect
        return value
    elif value is None:
        html = ''
    else:
        if isinstance(value, str):
            html = expand_db_html(value)
        else:
            raise TypeError("'richtext' template filter received an invalid value; expected string, got {}.".format(type(value)))

    return mark_safe('<div class="rich-text">' + html + '</div>')
示例#16
0
def richtext(value):
    if isinstance(value, RichText):
        # passing a RichText value through the |richtext filter should have no effect
        return value
    elif value is None:
        html = ''
    else:
        if isinstance(value, str):
            html = expand_db_html(value)
        else:
            raise TypeError("'richtext' template filter received an invalid value; expected string, got {}.".format(type(value)))

    return mark_safe('<div class="rich-text">' + html + '</div>')
示例#17
0
def try_expand_db_html(parsed_item):
    """
    expand_db_html errors out if not used on a string.
    becuase this process is so complicated, we wrap it in some error handiling
    so we can debug/catch an exception if someone adds a data schema later
    that causes problems
    """
    try:
        return expand_db_html(parsed_item)
    except Exception as e:
        print('Streamfield API Exception!', e)
        print(traceback.format_exc())
        return parsed_item
def richtext(value):
    if isinstance(value, RichText):
        # passing a RichText value through the |richtext filter should have no effect
        return value
    elif value is None:
        html = ''
    else:
        if isinstance(value, str):
            html = expand_db_html(value)
        else:
            raise TypeError(
                "'richtext' template filter received an invalid value; expected string, got {}."
                .format(type(value)))
    return render_to_string('wagtailcore/shared/richtext.html', {'html': html})
class AboutPage(Page):
    subpage_types = []
    max_count = 1
    about_content = StreamField([
        ('subheading', blocks.RichTextBlock(icon="title", features=['h2'])),
        ('paragraph',
         blocks.RichTextBlock(icon="pilcrow",
                              features=['p', 'link', 'bold', 'italic'])),
    ],
                                null=True)

    # Replace wrapped rich-text div
    RichText.__html__ = lambda self: expand_db_html(self.source)

    content_panels = Page.content_panels + [StreamFieldPanel('about_content')]
示例#20
0
    def test_expand_html_escaping_end_to_end(self, get_embed):
        get_embed.return_value = Embed(
            url='http://www.youtube.com/watch/',
            max_width=None,
            type='video',
            html='test html',
            title='test title',
            author_name='test author name',
            provider_name='test provider name',
            thumbnail_url='htto://test/thumbnail.url',
            width=1000,
            height=1000,
        )

        result = expand_db_html('<p>1 2 <embed embedtype="media" url="https://www.youtube.com/watch?v=O7D-1RG-VRk&amp;t=25" /> 3 4</p>')
        self.assertIn('test html', result)
        get_embed.assert_called_with('https://www.youtube.com/watch?v=O7D-1RG-VRk&t=25')
示例#21
0
 def accessible_links(html):
     """
     Makes footer links with surrounding text accessible
     to screen readers by adding an aria-label attribute
     containing the full text of the footer item to the link.
     """
     soup = BeautifulSoup(expand_db_html(html), 'html.parser')
     for p in soup.find_all('p'):
         if p.find_all('a'):
             for child in p.children:
                 if child.name == 'a':
                     if child.string != p.text:
                         child['aria-label'] = p.text
                 else:
                     if child.name != 'span':
                         child = child.wrap(soup.new_tag('span'))
                     child['aria-hidden'] = 'true'
     return str(soup).replace(u'\xa0', ' ')
示例#22
0
def get_field_value(instance, field_name: str):
    """
    Returns the value of a given field on an object of a StreamField.

    Different types of objects require different ways to access the values.
    """
    if isinstance(instance, StructValue):
        return instance[field_name]
    elif isinstance(instance.value, RichText):
        # Allow custom markup for RichText
        return render_to_string(
            "wagtailcore/richtext.html",
            {"html": expand_db_html(instance.value.source)})
    elif isinstance(instance.value, stream_block.StreamValue):
        stream_data = dict(instance.value.stream_data)
        return stream_data[field_name]
    else:
        return instance.value[field_name]
示例#23
0
    def item_extra_kwargs(self, item):
        """
        Returns an extra keyword arguments dictionary that is used with
        the 'add_item' call of the feed generator.
        Add the fields of the item, to be used by the custom feed generator.
        """
        if use_feed_image:
            feed_image = item.feed_image
            if feed_image:
                image_complete_url = urljoin(
                    self.get_site_url(), feed_image.file.url
                )
            else:
                image_complete_url = ""

        content_field = getattr(item, self.item_content_field)
        try:
            content = expand_db_html(content_field)
        except:
            content = content_field.__html__()

        soup = BeautifulSoup(content, 'html.parser')
        # Remove style attribute to remove large botton padding
        for div in soup.find_all("div", {'class': 'responsive-object'}):
            del div['style']
        # Add site url to image source
        for img_tag in soup.findAll('img'):
            if img_tag.has_attr('src'):
                img_tag['src'] = urljoin(self.get_site_url(), img_tag['src'])

        fields_to_add = {
            'content': soup.prettify(formatter="html"),
        }

        if use_feed_image:
            fields_to_add['image'] = image_complete_url
        else:
            fields_to_add['image'] = ""

        return fields_to_add
class NewsPage(Page):
    parent_page_type =[
        'news.NewsIndexPage'
    ]        
    subpage_types = []
    date = models.DateField("Post date")
    news_image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=False,
        on_delete=models.SET_NULL
    )

    # Replace wrapped rich-text div
    RichText.__html__ = lambda self: expand_db_html(self.source)

    news_content = StreamField([
        ('paragraph', blocks.RichTextBlock(icon="pilcrow", features=['p','link', 'bold', 'italic', 'ol', 'ul'])),
        ('image', ImageChooserBlock(icon="image")),
        ('quote', blocks.StructBlock([
            ('source', blocks.CharBlock(classname="full",
                                        help_text='The source of where that quote came from.')),
            ('quote_text', blocks.CharBlock(
                classname="full", help_text='Add quote.')),
        ], icon='openquote'), ),
        ('embedded_video', EmbedBlock(icon="media")),
    ], null=True)
    
    content_panels = Page.content_panels + [
        FieldPanel('date'),
        ImageChooserPanel('news_image'),
        StreamFieldPanel('news_content'),
    ]

    def first_paragraph(self):
        for block in self.news_content:
            if block.block_type == 'paragraph':
                return block.value
示例#25
0
 def test_expand_db_html_with_linktype(self):
     html = '<a id="1" linktype="document">foo</a>'
     result = expand_db_html(html)
     self.assertEqual(result, '<a>foo</a>')
示例#26
0
 def test_expand_db_html_with_embed(self, get_embed):
     from wagtail.embeds.models import Embed
     get_embed.return_value = Embed(html='test html')
     html = '<embed embedtype="media" url="http://www.youtube.com/watch" />'
     result = expand_db_html(html)
     self.assertIn('test html', result)
示例#27
0
 def resolve_description_html(self, info):
     return expand_db_html(self.description)
示例#28
0
 def resolve_body_html(self, info):
     return expand_db_html(self.content)
示例#29
0
 def serialize(value):
     return expand_db_html(value)
 def get_rich_text(self, page):
     return expand_db_html(page.rich_text)
示例#31
0
 def get_prep_value(self, value):
     return expand_db_html(value.source)
 def get_wysiwyg(self, page):
     return expand_db_html(page.wysiwyg)
示例#33
0
 def test_expand_db_html_with_linktype(self):
     html = '<a id="1" linktype="document">foo</a>'
     result = expand_db_html(html)
     self.assertEqual(result, '<a>foo</a>')
示例#34
0
 def resolve_value(self, value):
     # Allow custom markup for RichText
     return render_to_string("wagtailcore/richtext.html",
                             {"html": expand_db_html(self.value.source)})
示例#35
0
 def render(self, name, value, attrs=None):
     if value is None:
         translated_value = None
     else:
         translated_value = expand_db_html(value, for_editor=True)
     return super().render(name, translated_value, attrs)
示例#36
0
 def test_expand_db_html_no_linktype(self):
     html = '<a id="1">foo</a>'
     result = expand_db_html(html)
     self.assertEqual(result, '<a id="1">foo</a>')
示例#37
0
 def test_expand_db_html_no_linktype(self):
     html = '<a id="1">foo</a>'
     result = expand_db_html(html)
     self.assertEqual(result, '<a id="1">foo</a>')