I played around with the built-in comments app today, trying to clean it up.
Some findings:
1. Some of the moderation views, such as flagging a post or deleting a post, accept a next parameter that determines where the view will redirect to after the operation. However, the way the url's are set up, there's no easy way to pass this parameter normally, even through query strings. THis lovely bug is documented in http://code.djangoproject.com/ticket/8968. I wasn't confident enough to try patching it, so as a temporary workaround, I overrode the flag and delete templates and placed the following inside the form:
<input type="hidden" name="next" value="{{ comment.get_content_object_url }}" />
Edit: Wow that was stupid. Blogger didn't want to render the HTML code above!
I also replaced the URL in the "cancel" links for both pages. For some reason, {{ comment.permalink }} wasn't giving me anything useful.
2. Took me a bit of work to figure out how the moderation part works. Apparently I have to hook on some of the signals to add my moderation logic. I'm not sure yet how to handle this, or whether I should try customizing the comment form with something like a captcha to prevent comment spam.
3. I have a pending problem now that submitting comments from the preview or error page does not redirect to the correct place. (i.e. the post page). I tried adding the next parameter to the form, but apparently comment.get_content_object_url returns an empty string here because the comment has not yet been saved to the database. I think the content object should be provided in the context for the preview page. This would be handled by http://code.djangoproject.com/ticket/9268, except apparently no one's paying attention to it yet.
4. Some random features I added: Gravatar support (the Gravatar for the email address used to post the comment will be shown), and Markdown support in the comment body. Easy stuff.
5. Cleaned up an refactored the templates that render the comments, separating them from the parts that render the blog posts. This makes it easier if I want to have comments for other non-Blog post objects later.
Non-comment related:
1. Added simple search!
2. The script to import from Wordpress has some problems. Since I'm storing the post body in markdown format, I use html2text to convert the HTML body from old posts into markdown, but nice stuff like image alignments and tables are lost. I think I have to make do with editing straight HTML for old posts imported from Wordpress, and just clean them up later as needed.
My code is rather messy now (especially from the HTML side). I should clean it up sometime soon.
Monday, December 1, 2008
Sunday, November 23, 2008
Django Update - Wordpress Import and More
I've been busy at work so fell a bit behind with Django. Last night I worked on a Wordpress importer, so that I could migrate posts from my current blog(s) into the Django-powered blog that I'm coding. I'm using BeautifulSoup to parse the Wordpress export file and insert them as Django objects.
Since I was running the script repeatedly, I had to figure out how to easily run it from the command line, without having to run it from inside manage.py shell. After some searching, I found that what I needed to do was set an environment variable DJANGO_SETTINGS_FILE to point to my settings file. After that, the importer script could be run repeatedly.
Also made a few tweaks to my dev copy:
Stuff to do:
Since I was running the script repeatedly, I had to figure out how to easily run it from the command line, without having to run it from inside manage.py shell. After some searching, I found that what I needed to do was set an environment variable DJANGO_SETTINGS_FILE to point to my settings file. After that, the importer script could be run repeatedly.
Also made a few tweaks to my dev copy:
- Modified URL mapping to follow the permalinks of the old blog (so that people linking to me don't suddenly have broken links)
- Added a tag cloud (Still using django-tagging)
- Added markdown support to the admin maintenance screen. I used to think I would need to code my own form for posting, but I think I can live with just using the admin-provided one (initially at least)
Stuff to do:
- Use clean, non-hardcoded urls (url template tag and reverse())
- Customize the admin screen for posting
- Clean up the layout and templates
Sunday, October 26, 2008
django-tagging
I wanted to add some basic tagging to my blog app so I tried out django-tagging. Unfortunately, the featured downloads on the Google Code site are quite out-of-date and would not work with Django 1.0, so I did a subversion checkout instead. If you're getting an error like "ImportError: cannot import name parse_lookup", then you need to get the source code from SVN.
Adding the tagging to the blog was pretty easy:
1. Add the tagging app to settings.py
2. Add a tagging.fields.TagField to the Post model
3. Add a "tags" text field to the post form used.
4. Modify templates to display the tags.
5. I used something like "/tag/" url mapping to get all posts associated with a tag. Then you just need to write a wrapper around the object_list generic view:
This view will use the same template used to list out posts normally.
Adding the tagging to the blog was pretty easy:
1. Add the tagging app to settings.py
2. Add a tagging.fields.TagField to the Post model
3. Add a "tags" text field to the post form used.
4. Modify templates to display the tags.
5. I used something like "/tag/
from tagging.models import Tag, TaggedItem
from django.views.generic.list_detail import object_list
def posts_by_tag(request, tag):
o_tag = Tag.objects.get(name=tag)
queryset = TaggedItem.objects.get_by_model(Post, o_tag)
return object_list(request, queryset)
This view will use the same template used to list out posts normally.
Friday, October 24, 2008
I left it for a while...
...and now it works!
http://www.randomencounters.bells-n-whistles.net/blog/
I think the apache service needed to restart mod_python or something...(I don't have SSH access so...)
http://www.randomencounters.bells-n-whistles.net/blog/
I think the apache service needed to restart mod_python or something...(I don't have SSH access so...)
Tuesday, October 21, 2008
Deployment Problems
So I got a basic blog app up and running.
Posting, paged archives, etc.
Comments implemented using the django.contrib.comments. No problems here, the only caveat being most of the current documentation found by Google searches refer to the pre-1.0 version. Need to peruse the official docs for 1.0 stuff.
RSS feeds implemented using django.contrib.syndication, this one seems fine.
I tested it and it's running fine on localhost. I also have a free django hosting account at http://bells-n-whistles.net, so I try to upload it there. However, when I access the website there (http://www.randomencounters.bells-n-whistles.net/blog/), I get the following error:
Posting, paged archives, etc.
Comments implemented using the django.contrib.comments. No problems here, the only caveat being most of the current documentation found by Google searches refer to the pre-1.0 version. Need to peruse the official docs for 1.0 stuff.
RSS feeds implemented using django.contrib.syndication, this one seems fine.
I tested it and it's running fine on localhost. I also have a free django hosting account at http://bells-n-whistles.net, so I try to upload it there. However, when I access the website there (http://www.randomencounters.bells-n-whistles.net/blog/), I get the following error:
'comments' is not a valid tag library: Could not load template library from django.templatetags.comments, No module named comments
I think the settings.py is not being reloaded - I tried to set Debug = False and I'm still getting the stacktraces.
Bah, I'll figure it out tomorrow.
Monday, October 20, 2008
"when redirecting, how can I make the redirect URL decoupled from the urls.py of the parent app?"
-> It turns out that HttpResponseRedirect supports relative paths, so this was fine.
return HttpResponseRedirect("../" + str(post.id) + "/")
I got the basic posting structure up.
/post/new/ -> To make new posts
/post// -> To view a single post
/post/all/ -> To view all posts
I should probably start thinking of a better url scheme. Ideally, I'd want the @login_required views to be indicated as such in the urls. Something like "/admin/post/" for new posts "/admin/manage/" for a screen to manage posts to differentiate it from a screen just to list them out.
Next I think I'll try to CSS-ify the blog; I'll probably just reuse stuff from one of the blogger templates as I'm still not very good with the HTML/CSS.
I'll also look into using some of the date-based generic views to get an archive view. I'll need more data though. Will consider importing from the Wordpress blog.
-> It turns out that HttpResponseRedirect supports relative paths, so this was fine.
return HttpResponseRedirect("../" + str(post.id) + "/")
I got the basic posting structure up.
/post/new/ -> To make new posts
/post/
/post/all/ -> To view all posts
I should probably start thinking of a better url scheme. Ideally, I'd want the @login_required views to be indicated as such in the urls. Something like "/admin/post/" for new posts "/admin/manage/" for a screen to manage posts to differentiate it from a screen just to list them out.
Next I think I'll try to CSS-ify the blog; I'll probably just reuse stuff from one of the blogger templates as I'm still not very good with the HTML/CSS.
I'll also look into using some of the date-based generic views to get an archive view. I'll need more data though. Will consider importing from the Wordpress blog.
Sunday, October 19, 2008
Starting out
The quintessential app to learn from is of course a blog.
Started using a simple Post model. Added the new post form and view. Can now successfully insert posts into the DB.
Next:
- create the detail page that will show the post after saving
Figure out:
- when redirecting, how can I make the redirect URL decoupled from the urls.py of the parent app?
i.e. if the parent app has the following mapping:
'^blog/' -> pass to blog.urls.urlpatterns
the blog app has mappings for
'^post/new/' -> new post
'^post/([A-Za-z\-])/' -> post detail
inside the view, I want to redirect to "post/", but with respect to the app, it should be "blog/post/"
I should subscribe to one of the Django mailing lists to ask stuff like this.
Started using a simple Post model. Added the new post form and view. Can now successfully insert posts into the DB.
Next:
- create the detail page that will show the post after saving
Figure out:
- when redirecting, how can I make the redirect URL decoupled from the urls.py of the parent app?
i.e. if the parent app has the following mapping:
'^blog/' -> pass to blog.urls.urlpatterns
the blog app has mappings for
'^post/new/' -> new post
'^post/([A-Za-z\-])/' -> post detail
inside the view, I want to redirect to "post/
I should subscribe to one of the Django mailing lists to ask stuff like this.
Subscribe to:
Posts (Atom)