Hello I'm using ckeditor to generate content, and I'm trying to get a thumbnail of image if image got generated.
In my models.py
from goose import Goose
class Post(models.Model):
content = RichTextUploadingField(config_name='default')
def thumbnail(self):
g = Goose()
thumbnail = g.extract(content=self.content)
return thumbnail
I thought I would extract image with python goose extractor, I thought this is the right way, but soon realized I might be approaching it wrong.
In my html file,
{{ post.content|safe }}
{{ post.thumbnail }}
content is generated like above, but I don't get any thumbnail. Am I approaching it wrong?is there any other way I can extract the image from the content that's made by user by wysiwyg editor
Edit:
def thumbnail(self, content):
g = Goose()
thumbnail = g.extract(content=self.content).top_image.src
return thumbnail
In html
<img src="{{ post.thumbnail }}" />
Goose.extract() returns an article object, not a thumbnail. Try:
thumbnail = g.extract(raw_html=self.content).top_image.src
this will return an URL for the main image of the article. You can then use it in your templates like this:
<img src="{{ post.thumbnail }}">
Related
I will preface by saying this is my first time working with flask & HTML to build a web app, so I may be using the wrong terminology in some places, apologies in advance.
I have used these two previous questions as reference for what i'm doing:
Flask render a word cloud
Passing a matplotlib figure to HTML (flask)
I am working a web app that allows a user to input a movie, and a wordcloud is returned.
The user starts on /search, where they input a movie name, I then redirect to /search_results where a list of movies with similar names are shown, the user selects the right film and submits. This part of the journey is all working fine, from here I take the movie name, I then apply a function I have built in python that creates a wordcloud based on this film name (in my code below this is what the function wordcloud_generator(1,session['search_value']) is doing in the fig route). The output of the wordcloud_generator() function is:
...
img = BytesIO()
wordcloud.to_image().save(img, 'PNG')
img.seek(0)
return img
I want to save this image to a route "/fig/<wordcloud_img>" and then be able to call it in the src of an img tag in the route "/images/<wordcloud_img>".
When running through this I get the error of at the point that I submit the movie name from /search_results and redirect to 'images'. Error: werkzeug.routing.BuildError: Could not build url for endpoint 'images'. Did you forget to specify values ['wordcloud_img']?
After this if I navigate manually to "localhost:5000/fig/wordcloud_img" then my function seems to run and the image is shown, and then if I manually navigate to "localhost:5000/images/wordcloud_img" the image is properly surfaced in the html.
It seems like I am doing this in the wrong order somehow and the function isn't running/generating the image before I try to access it on the /images source.
Routes
def search():
if request.method == 'POST':
movie_search = request.form['search_text']
session['returned_movies'], session['search_links'] = search_function(search_term = movie_search)
return redirect(url_for('search_result'))
return render_template('search.html',title='Search')
#app.route("/search_result", methods=['GET', 'POST'])
def search_result():
if request.method == 'POST':
movie = request.form['movie']
session['search_value'] = session['search_links'][session['returned_movies'].index(movie)]
return redirect(url_for('images'))
return render_template('search_results.html',title='Search Results')
#app.route("/images/<wordcloud_img>")
def images(wordcloud_img):
return render_template("wordcloud.html")
#app.route("/fig/<wordcloud_img>")
def fig(wordcloud_img):
img = wordcloud_generator(1,session['search_value'])
return send_file(img, mimetype='image/png')
wordcloud.html
{% extends "layout.html" %}
{% block content %}
<div>
{% if session['search_value'] %}
<p>Searching for a movie: {{ session['search_value'] }}</p>
{% else %}
<p>Oops, no movie selected </p>
{% endif %}
<body>
<img src="{{ url_for('fig', wordcloud_img = 'wordcloud_img') }}" alt="Image Placeholder" height="100">
</body>
</div>
{% endblock content %}
The problem is that you are not passing the image to the 'images' function that displays the template with the image. In your 'search_result' function, you will need to pass the wordcloud_image to the 'images' function like so:
return redirect(url_for('images'), wordcloud_img=your_image)
(replacing your_image with the actual image variable)
In your images route, you would then need to pass this received image to the template:
return render_template("wordcloud.html", wordcloud_img=wordcloud_img)
Then in your template, you can use this wordcloud_img variable like this:
<img src="{{ url_for('fig', wordcloud_img=wordcloud_img) }}" alt="Image Placeholder" height="100">
This is how I wrote the gallery function which is supposed to display images stored in MongoDB using GridFS:
#app.route('/gallery/<username>')
def gallery(username):
user = db.users.find_one({'username': username})
images = user['images']
for img in images:
image = grid_fs.get(img)
base64_data = codecs.encode(image.read(), 'base64')
image = base64_data.decode('utf-8')
return render_template('gallery.html')
How am I supposed to write the HTML document in order for the photos to be displayed?
First, you need to return data to template:
return render_template('gallery.html', **images)
And then you can use it in your template like this:
{% for img in images %}
<img src="data:image/png;base64, {{ img }}">
{% endfor %}
Here is the problem, I'm a bit lost with foreignkey, i've seen a lot of post and i don't understand everything.
I have a item table:
class Item(models.Model):
title = models.CharField(max_length=150)
slug = models.SlugField(max_length=100)
price = models.IntegerField()
stock = models.IntegerField()
description = models.TextField()
image = models.ImageField(upload_to=item_file_name)
There is an image wich is the principal. On my index when I list all my item I want to see the image of each item. But when I click on the item I want to see all of the image of this item (in another view). So I've done this.
class ImageOfItem(models.Model):
picture = models.ImageField(upload_to=item_file_name_for_image)
item = models.ForeignKey('Item')
I don't know if it's good but it's working. I can add an item with a picture on the admin panel. And then I can add an image and attach it to the item.(it works, the best way would be to be able to upload all the image when creating the item but I prefer to start easy).
So know everything is save as I want. But I don't know how to display all the images.
My view looks like this:
def view_item(request, id, slug):
item = get_object_or_404(Item, id=id)
return render(request, 'ecommerce/view_item.html', locals())
I don't know if I have to get images too or if django already done it. and there is no var_dump so no way to know if it's in my variable item
my template:
{{item.title}}
{{item.description}}<br>
{{item.price}}<br>
{{item.stock}}<br>
<img src="{{ item.image.url }}"><br> //principal image it works !!
{% for img in item.ImageOfItem %}
<img src="{{ img.picture.url }}"><br> //**all the image I want to display too (but don't know how)**
{% endfor %}
all the image I want to display too (but don't know how)
You should follow relationship backward from Item to ImageOfItem:
{% for img in item.imageofitem_set.all %}
<img src="{{ img.picture.url }}"><br>
{% endfor %}
I have a url linked to a view that returns an image (successfully).
I am trying to use this url as a value of <img> tag src attribute inside template html file.
urls.py
url(r'^$',views.index,name='index'),
url(r'^image/(?P<graph_name>[a-zA-z]+)$', views.dynamic_image, name='dynamic-image'),
)
views.py
def dynamic_image(request, graph_name):
image=functionToCreateImage(graph_name)
return HttpResponse(image, content_type="image/svg+xml")
def index(request):
template = loader.get_template('graphs/index.html')
context = RequestContext(request, {
'gene_links_graph':reverse('dynamic-image', args=['gene_links_graph'])})
return HttpResponse(template.render(context))
index.html
...
<a href = "{{ gene_links_graph }}">
<img scr="{{ gene_links_graph }}" alt="img1">
</a>
...
The image renders on a new page via link, but does not appear on index.html page. How to fix that?
upd rendered html page source
<a href = "/graphs/image/gene_links_graph/">
<img scr="/graphs/image/gene_links_graph/" alt="img1">
</a>
There is a similar thread, but it didn't work in my case
django: serve dynamic (reportlab) png to template
Why is the generated HTML <img scr=""> instead of <img src="">? Could that be your problem?
I am using WMD in a google app situation whereby the site administrator can update the pages of the site and the users see the information.
The preview function is working fine and I can see the text the way I want it to appear, but when I am in the users section, the markdown is being returned without the formatting - how can i fix this?
This is the code i am using
{% block content-left %}
{% if is_admin %}
<div id="content-bodyleft" class="wmd-preview"></div>
<form action="/admin/content/" method="post">
<textarea id="markdown" name="markdown" style="width: 400px; height: 200px;" >{{ page_content.html }}</textarea>
<input name="page" type="hidden" value="{{ request.path }}" />
<input type="submit" name="Save" />
</form>
<div class="wmd-output"></div>
<script type="text/javascript">
// to set WMD's options programatically, define a "wmd_options"
// object with whatever settings
// you want to override. Here are the defaults:
wmd_options = {
// format sent to the server. Use "Markdown" to return the markdown source.
output: "Markdown",
// line wrapping length for lists, blockquotes, etc.
lineLength: 40,
// toolbar buttons. Undo and redo get appended automatically.
buttons: "bold italic | link blockquote code image | ol ul heading hr",
// option to automatically add WMD to the first textarea found.
// See apiExample.html for usage.
autostart: true
};
</script>
<div class="wmd-output"></div>
<script type="text/javascript" src="/static/wmd/wmd.js"></script>
{% else %}
{{ page_content.html|markdown }}
{% endif %}
The reason this is happening is because the Django Form is only seeing the value of the <textarea> tag that represents WMD editor. That value is the actual markdown, not the rendered HTML that you see in the preview.
There are several ways to fix this, on either the client or the server...
When the form is saved, convert the markdown to HTML on the server using a python markdown module, like this one
When the form is submitted on the client, have javascript replace the value of the WMD <textarea> tag to the actual HTML
Option #1 is probably the easiest. Here's some sample code...
import markdown
class MyModel(models.Model):
text = models.TextField()
def save(self, force_insert=False, force_update=False):
if self.text:
self.text = markdown.markdown(self.text)
super(MyModel, self).save(force_insert, force_update)
This doesn't appear to have anything to do with WMD.js, which is an editor and has nothing to do with displaying the content.
You don't post your models, but it looks like you are entering content into the "markdown" field, but displaying a different field, "html". I presume you have something in your models - maybe on save - that populates that html field with the converted markup?
Also are you sure you're seeing raw markdown, or are you seeing raw HTML? I would assume you would need to unescape the html output:
{{ page_content.html|safe }}
This is my models.py file
# models.py
from google.appengine.ext import db
class GoogleToken(db.Model):
session_token = db.StringProperty()
scope_url = db.StringProperty()
added_on = db.DateTimeProperty(auto_now_add=True)
class PageContent(db.Model):
html = db.TextProperty()
page = db.StringProperty()
class PageMedia(db.Model):
name = db.StringProperty()
type = db.StringProperty()
content = db.BlobProperty(default=None)
class Announcement(db.Model):
title = db.StringProperty()
content = db.TextProperty()
added_on = db.DateTimeProperty(auto_now_add=True)
and this is from views.py
def content(request):
html = request.POST.get('markdown', None)
page = request.POST.get('page', None)
logging.debug(html)
logging.debug('Page: %s' % page)
query = PageContent.all().filter('page =', page)
page_content = query.get()
if page_content == None:
page_content = PageContent(html=html,page=page)
else:
page_content.html = html
To help you understand what is happening, for example I am typing
Title
----
*Subtitle*
Text text text
and seeing
Title
Subtitle
Text text text
in preview, but on output i am seeing
Title----*Subtitle*Text text text
Thanks, I do appreciate your help with this.