This is a blogging platform with a bit of twist. It's been optimized for… memes and other similar cool stuff!
It's also a regular blogging platform. Obviously.

In most blogging platforms, if you want to include a popular meme or an xkcd comic, you normally have to search for it separately and paste the URL in the image box, or go to a meme generator, make the meme, download it, upload it… well you get the idea.

Blag changes all this! In our custom flavour of Markdown, we have a snazzy new tag called [magic]. This tag will try and best fit anything between [magic] and [/magic] to what you want.

In case you were wondering, we named this project Blag in honour of xkcd.

We used Heroku to deploy our website. Check it out on!

More on Markdown-Magic


Install it using pip:

$ pip install markdown-magic


For memes

Simply do

[magic] meme: top_text | bottom_text [/magic]

for whichever meme template you want to use, and markdown-magic will detect which template to use on its own.

Markdown-magic currently supports the following meme templates:

  • Lord of the Rings Boromir - "One does not simply"
  • The Most Interesting Man in the World - "I don't always… when I do"
  • Ancient Aliens History Channel Guy
  • Grumpy Cat
  • Buzz Lightyear and Woody from Toy Story - "X, X everywhere"
  • Futurama Fry - "Not sure if…"
  • Y U NO Guy
  • Ned Stark from Game of Thrones - "Brace yourself/yourselves…"
  • X all the Y
  • Bill Lumburgh from Office Space - "…that would be great"
  • The rent is too damn high
  • The Big Lebowski - "Am I the only one around here…"
  • Matrix Morpheus - "What if I told you…"
  • Ain't nobody got time for that
  • Heath Ledger Joker - "Nobody bats an eye… everyone loses their minds"

More to be added soon!

For gifs

Just type in

[magic] gif: <list of space-separated search parameters> [/magic]

and markdown-magic will search and use the appropriate gif according to the given search parameters.

Here's an example on the Python interpreter:

>>> import markdown
>>> text = """
... [magic] meme: rains | y u no happen during summers [/magic]
... Some text here.
... [magic] gif: spongebob squarepants [/magic]
... """
>>> print(markdown.markdown(text, extensions=['magic']))
<p><img alt="meme: rains | y u no happen during summers " src="" title="meme: rains | y u no happen during summers " />
Some text here.
<img alt="gif: spongebob squarepants " src="" title="gif: spongebob squarepants " /></p>

For more information and the complete source code, please visit the markdown-magic git repo. The code is open-sourced and licensed under the MIT license.

Team members and Responsibilities

Team member Responsibility
Anubhav Jain Frontend, Templates
Ishbir Walia Templates, Content
Radhika Ghosal Backend, Markdown-magic
Raunak Sinha Backend, Templates



What we learned and used to make Blag

  • Django
  • HTML5
  • CSS3
  • Bootstrap
  • Python Markdown
  • Heroku

Steps of the Journey

We decided to develop a blogging website. Right off the hook, Radhika came up with the idea of [magic]. She explained it to us, and the idea seemed pretty cool, so we all agreed to make Blag.

So our journey started by learning Django. So after a lot of study on Django and how MVC frameworks work, we started building the app. The Django Documentation really helped us out!

  • We first coded the Models, ie. the database objects which represent the various components of the app like posts, comments, and categories.
  • Next, we worked on the Views, ie. the python functions which determine how the data from the models is served to the webpage and client.
  • Then we wrote the Templates, ie. the HTML pages which render the data received from the Views.

After completing the Backend, we then moved on to beautifying the Frontend.

For this, we learnt HTML and CSS, and used Bootstrap to make the site visually appealing and responsive.

Finally, we migrated from using sqlite3 as our database to postgresql, and deployed our app on Heroku. Click here to check it out!

Code Snippets


class Post(models.Model):
    author = models.ForeignKey(User)
    title = models.CharField(max_length=100, unique=True)
    text = models.TextField()
    # A 'slug' is a short label used as a unique identifier in urls.
    text_html = models.TextField(editable=False, blank=True, null=True)
    # This is set as non-editable so that markdown can set the HTML
    # for the post.
    created_on = models.DateTimeField(db_index=True, auto_now_add=True)
    slug = models.SlugField(max_length=100, unique=True)
    categories = models.ManyToManyField(Category)
    published = models.BooleanField(default=True)
    objects = PostQuerySet.as_manager()
    # We set PostQuerySet as the default QuerySet manager for the Post model.
    # We set it as objects, because we always tend to call Post.objects.whatever(some params)
    # to create a QuerySet.
    def save(self):
        # self.text_html = markdown2.markdown(self.text, extras=['fenced-code-blocks'])
        self.text_html = markdown.markdown(self.text, extensions=['markdown.extensions.extra', 'magic'])
        super(Post, self).save()


class PostDisplay(DetailView):
    model = Post
    template_name = "post.html"
    def get_context_data(self, **kwargs):
        Insert into the context dict.
        context = super(PostDisplay, self).get_context_data(**kwargs)
        post = self.object
        context['comment_list'] = Comment.objects.filter(post=post)
        context['form'] = CommentForm()
        return context


{% extends "base.html" %}
{% load django_markdown %}
{% block title %}
    Blag | {{ object.title }}
{% endblock %}
{% block blog_posts %}
    <div class="post">
        <h2><a href="{% url "post_detail" slug=object.slug %}">{{ object.title }}</a></h2>
        <p class="meta">
            {{ object.created_on }} |
            tagged under 
            {% for category in object.categories.all %}
                <a class="post-category post-category-js" href="{% url "category_index" slug=category.slug %}">{{ category }}</a>
            {% endfor %}
        {{ object.text_html|safe }}


class MagicPattern(Pattern):
    def handleMatch(self, m):
        Handles user input into [magic] tag, processes it,
        and inserts the returned URL into an <img> tag
        through a Python ElementTree <img> Element.
        userStr =
        # print(userStr)
        imgURL = processString(userStr)
        # print(imgURL)
        el = etree.Element('img')
        # Sets imgURL to 'src' attribute of <img> tag element
        el.set('src', imgURL)       
        el.set('alt', userStr)
        el.set('title', userStr)
        return el

All our code is in the public domain, so do check out the blag and the markdown-magic git repos for the complete source code. The code is open-sourced and licensed under the MIT license, so feel free to contribute to it!


Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License