Bladeren bron

Merge pull request #200 from khuevu/master

Add a plugin to extract representative image for an article
Justin Mayer 10 jaren geleden
bovenliggende
commit
47f5050463

+ 8 - 0
representative_image/Readme.md

@@ -0,0 +1,8 @@
+# Summary
+
+This plugin extracts a representative image (i.e, featured image) from the article's summary or article's content. The image can be access at `article.featured_image`. 
+
+The plugin also remove any images from the summary after extraction to avoid duplication. 
+
+It allows the flexibility on where and how to display the featured image of an article together with its summary in a template page. For example, the article metadata can be displayed in thumbnail format, in which there is a short summary and an image. The layout of the summary and the image can be varied for aesthetical purpose. It doesn't have to depend on article's content format. 
+

+ 1 - 0
representative_image/__init__.py

@@ -0,0 +1 @@
+from .representative_image import *

+ 31 - 0
representative_image/representative_image.py

@@ -0,0 +1,31 @@
+from pelican import signals
+from pelican.contents import Content, Article
+from bs4 import BeautifulSoup
+
+def images_extraction(instance):
+    representativeImage = None
+    if type(instance) == Article:
+        # Process Summary:
+        # If summary contains images, extract one to be the representativeImage and remove images from summary
+        soup = BeautifulSoup(instance.summary, 'html.parser')
+        images = soup.find_all('img')
+        for i in images:
+            if not representativeImage:
+                representativeImage = i['src']
+            i.extract()
+        if len(images) > 0:
+            # set _summary field which is based on metadata. summary field is only based on article's content and not settable
+            instance._summary = unicode(soup)
+        
+        # If there are no image in summary, look for it in the content body
+        if not representativeImage:
+            soup = BeautifulSoup(instance.content, 'html.parser')
+            imageTag = soup.find('img')
+            if imageTag:
+                representativeImage = imageTag['src']
+        
+        # Set the attribute to content instance
+        instance.featured_image = representativeImage
+
+def register():
+    signals.content_object_init.connect(images_extraction)

+ 54 - 0
representative_image/test_representative_image.py

@@ -0,0 +1,54 @@
+#!/bin/sh
+import unittest
+
+from jinja2.utils import generate_lorem_ipsum
+
+# Generate content with image 
+TEST_CONTENT_IMAGE_URL = 'https://testimage.com/test.jpg' 
+TEST_CONTENT = str(generate_lorem_ipsum(n=3, html=True)) + '<img src="' + TEST_CONTENT_IMAGE_URL + '"/>'+ str(generate_lorem_ipsum(n=2,html=True))
+TEST_SUMMARY_IMAGE_URL = 'https://testimage.com/summary.jpg'
+TEST_SUMMARY_WITHOUTIMAGE = str(generate_lorem_ipsum(n=1, html=True))
+TEST_SUMMARY_WITHIMAGE = TEST_SUMMARY_WITHOUTIMAGE + '<img src="' + TEST_SUMMARY_IMAGE_URL + '"/>'
+
+
+from pelican.contents import Article
+import representative_image
+
+class TestRepresentativeImage(unittest.TestCase):
+
+    def setUp(self):
+        super(TestRepresentativeImage, self).setUp()
+        representative_image.register()
+
+    def test_extract_image_from_content(self): 
+        args = {
+            'content': TEST_CONTENT,
+            'metadata': {
+                'summary': TEST_SUMMARY_WITHOUTIMAGE,
+            },
+        }
+
+        article = Article(**args)
+        self.assertEqual(article.featured_image, TEST_CONTENT_IMAGE_URL)
+
+    def test_extract_image_from_summary(self):
+        args = {
+            'content': TEST_CONTENT,
+            'metadata': {
+                'summary': TEST_SUMMARY_WITHIMAGE,
+            },
+        }
+
+        article = Article(**args)
+        self.assertEqual(article.featured_image, TEST_SUMMARY_IMAGE_URL)
+        self.assertEqual(article.summary, TEST_SUMMARY_WITHOUTIMAGE)
+
+if __name__ == '__main__':
+    unittest.main()
+        
+
+
+
+
+
+