As everyone knows, internet comments are pure, unadulterated evil.1 But it’s nonetheless nice when blogs give readers an easy way to provide feedback. I recently reworked my Octopress installation to allow readers to reply to my posts via Twitter or email; this post will show you how to set it up for yourself. We’ll be using Twitter’s Web intents API to make it happen.

Step 1: Configuration

If you haven’t already set your Twitter username in your Octopress _config.yml, do so now; here’s what mine looks like:

# Twitter
twitter_user: willb
twitter_tweet_button: false

Step 2: Create a new partial layout

The next thing we’ll do is add a new partial layout that generates reply-via-Twitter links. Create source/_includes/post/feedback.html in your Octopress directory and give it the following contents:

 • You may 
 {% if site.twitter_user and page.skip_twitter_feedback != true %}
    <script type="text/javascript" src="//"></script>
    {% capture tweet_text %}@{{site.twitter_user}} re: {{site.url}}{{page.url}}{% endcapture %}
  <a href="{{ tweet_text | uri_escape }}">reply to this post on Twitter</a> or
 {% endif %}
<a href="mailto:{{}}">email the author</a>.

Note that this will always provide an email feedback link, targeting the site-wide email variable from your _config.yml.2 It will provide reply-via-twitter links if you’ve set the twitter_user configuration variable and haven’t set skip_twitter_feedback: true in your post’s YAML front matter. (I use this to eliminate redundancy for cases like this, in which I’ve asked for replies via Twitter in the body of the post.) When a reader clicks on the reply-via-twitter link, it will take them to Twitter3 with a prepopulated tweet:

Web Intent

Step 3: Add the new partial to your post template

Finally, edit your post template to ensure that it includes feedback.html in an appropriate place. This will obviously depend on your theme and your taste, but I’ve included my post template – which is based on octostrap3 and includes the feedback links directly following the category list – as an example; see line 19:

layout: default
navbar: Blog
single: true

<div class="row">
  <div class="page-content {% unless page.sidebar == false or site.post_asides == empty and site.default_asides == empty %}col-md-9{% else %}col-md-12{% endunless %}" itemscope itemtype="">
    <meta itemprop="name" content="{{site.title}}" />
    <meta itemprop="description" content="{{site.description}}" />
    <meta itemprop="url" content="{{site.url}}" />
    <article class="hentry" role="article" itemprop="blogPost" itemscope itemtype="">
      {% include article.html %}
        <p class="meta text-muted">
          {% include post/author.html %}
          {% include post/date.html %}{% if updated %}{{ updated }}{% else %}{{ time }}{% endif %}
          {% include post/categories.html %}
          {% include post/feedback.html %}
        {% unless page.sharing == false %}
          {% include post/sharing.html %}
        {% endunless %}
        {% if page.previous.url or %}
          <ul class="meta text-muted pager">
            {% if page.previous.url %}
            <li class="previous"><a href="{{page.previous.url}}" title="Previous Post: {{page.previous.title}}">&laquo; {{page.previous.title}}</a></li>
            {% endif %}
            {% if %}
            <li class="next"><a href="{{}}" title="Next Post: {{}}">{{}} &raquo;</a></li>
            {% endif %}
        {% endif %}
    {% if site.disqus_short_name and page.comments == true %}
        <div id="disqus_thread" aria-live="polite">{% include post/disqus_thread.html %}</div>
    {% endif %}

  {% unless page.sidebar == false or site.post_asides == empty and site.default_asides == empty %}
  <aside class="sidebar col-md-3">
    {% if site.post_asides.size %}
      {% include_array post_asides %}
    {% else %}
      {% include_array default_asides %}
    {% endif %}
  {% endunless %}

Step 4: There is no Step 4

I hope this was helpful! If you have feedback on this post, I bet you can figure out where to find me.

  1. Only mostly kidding. 

  2. If you haven’t sent this variable, you can replace {{}} with your email address. You can also replace the whole mailto link with the results of some obfuscation technique like the Hivelogic Enkoder if you still care about concealing your email address from spambots. 

  3. By default, it will open this in a pop-up window unless your users are blocking Javascript from Twitter. If you’re interested in avoiding pulling down scripts from external sites, eliminating the script link to will only disable the pop-up window, not affect reply-via-tweet functionality in general. (You can, of course, use well-known techniques to open the link in a pop-up window without the external script.) 

• You may reply to this post on Twitter or