Older blog entries for ralsina (starting at number 700)

Standalone Search in Nikola

This has been in the master branch of Nikola for a while but only now have I tried to fully integrate it, and polish all (most) of the rough edges.

By default, Nikola comes with support for search forms using Google and Duckduckgo. Some people disapprove of them for different reasons [1] so there was a request about supporting a standalone search engine.

The best of breed of those things seems to be Tipue so that's what I supported.

To use this, you need to enable a plugin, and do some configuration changes.

The plugin is called task_localsearch and you can find it in the Nikola source tree

Suppose your site is in a folder called mysite then to enable this plugin you need to create mysite/plugins and then copy task_localsearch.plugin and task_localsearch in there.

Then, in your site's conf.py find these options and change them accordingly:

SEARCH_FORM = """
<form action="#" class="navbar-form pull-left">
<input type="text" id="tipue_search_input">
</form>"""

ANALYTICS = """
<script type="text/javascript" src="/assets/js/tipuesearch_set.js"></script>
<script type="text/javascript" src="/assets/js/tipuesearch.js"></script>
<script type="text/javascript">
$(document).ready(function() {
    $('#tipue_search_input').tipuesearch({
        'mode': 'json',
        'contentLocation': '/assets/js/tipuesearch_content.json',
        'showUrl': false
    });
});
</script>
"""

EXTRA_HEAD_DATA = """
<link rel="stylesheet" type="text/css" href="/assets/css/tipuesearch.css">
<div id="tipue_search_content" style="margin-left: auto; margin-right: auto; padding: 20px;"></div>
"""

How does it work? Here's a demo site for you to try!

I would not recommend doing this for a big site, since it may load a multi-megabyte javascript file when you search, but for small to medium sites, it may be ok.

[1] My own reason for disapproving of duckduckgo site search? It finds nothing.

Syndicated 2013-03-12 20:09:06 from Lateral Opinion

Unfortunate Phrases by Famous People

Like this one:

When your country is at risk, everything is allowed, except not defending it.

—José de San Martín

For non-argentinian readers, imagine if that was said by a combination Washington/Lincoln level figure famous for leading three countries to get rid of the spaniards and also for a list of advices for young ladies, whose biography is titled "The saint with a sword".

So, anyway, he said that. And that phrase is bad, bad, bad, unfortunate and horrible.

It's that bad because while a nice slogan to rally farmers into becoming soldiers in the army of a nation that doesn't quite exist yet, it's awful advice for people who live in an actual nation, with actual laws, an actual army, and people who worship whatever crap you happened to say, José.

It starts with the flaky premise "when your country is at risk" which means too little, or too much, depending on just how much you need an excuse to do something horrible.

If you really want to be a bad person, I am sure you can convince yourself that gays, immigrants, foreigners, muslims, jews, the young are all a danger to your country, somehow. You just need to stretch "danger" a little or maybe push "your country" somewhat.

And once you jumped that hurdle, and you are convinced your "country" is "at risk", why, then you can do anything. Unsurprisingly this stupid line is often framed in military offices, and is a tired trope in military speeches.

I quite like José de San Martín. This quote, however, is unfortunate.

Syndicated 2013-03-11 18:15:34 from Lateral Opinion

Doing Your Homework, With Style

Note

The original poster claims this is not a school homework. Accepting that, it still doesn't mean how to answer to homework requests is not worthy of discussion.

As usual in all programming lists, every once in a while someone will post a question in the Python Argentina list which is obviously his homework. To handle that there are two schools of thought.

  1. Telling the student how to do it is helping them cheat.
  2. Telling the student how to do it is teaching him.

I tend more towards 1) but I think I have discovered a middle road:

1.5) Tell the student a solution that's more complicated than the problem.

That way, if he figures out the solution, he has done the work, and if he doesn't figure it out, it's going to be so obviously beyond his skill the teacher will never accept it as an answer.

As an example, here's the problem for which help was requested:

Given an unsorted list of two-letter elements (une lowercase, one uppercase), for example:

['eD', 'fC', 'hC', 'iC', 'jD', 'bD', 'fH', 'mS', 'aS', 'mD']

Sort it by these criteria:

  1. Create subsets according to the uppercase letter, and sort them by the number of members in ascending order, like this:

    ['fH', 'mS', 'aS', 'fC', 'hC', 'iC', 'jD', 'bD', 'eD', 'mD']
    
  2. Then sort each subset in ascending order of the lowercase letter, like this:

    ['fH', 'aS', 'mS', 'fC', 'hC', 'iC', 'bD', 'eD', 'jD', 'mD']
    

Ignoring that the problem is not correctly written (there are at least two ways to read it, probably more), I proposed this solution, which requires python 3:

from collections import defaultdict
d1 = defaultdict(list)
[d1[i[1]].append(i) for i in  ['eD', 'fC', 'hC', 'iC', 'jD', 'bD', 'fH', 'mS', 'aS', 'mD']]
{i: d1[i].sort() for i in d1}
d2 = {len(d1[i]): d1[i] for i in d1}
print([item for sublist in [d2[i] for i in sorted(d2.keys())] for item in sublist])

This produces the desired result: ['fH', 'aS', 'mS', 'fC', 'hC', 'iC', 'bD', 'eD', 'jD', 'mD'] but it's done in such a way that to understand it, the student will need to understand roughly three or four things he has probably not been taught yet.

Syndicated 2013-03-10 20:23:32 from Lateral Opinion

A Django Le Saltó La Cadena

Sorry, spanish only post!

Syndicated 2013-03-10 09:35:49 from Lateral Opinion

A Few Problems with A Song Of Ice and Fire

I read all of it, one book after the other, and ended a month ago. And since then, I have had a couple of things about it bothering me. Let's see if they make some sense. Mind you, I am going to read volumes six and seven, because these books are addictive as crack in ebook-form.

But, just like crack, they have some worrisome features.

There May Be No Plan

We are five books (and a couple of chapters) into it. It's supposed to be a seven book series. And nothing has happened. You may say a lot has, like "this character got killed" and "that other character got killed" (and a hundred other characters got killed), yeah.

But what has changed in the five kingdoms?

It's starting to feel, these many pages later, as if ... well, who cares what happens? The five kingdoms will have a king, or another. There will be dragons (which will support a king or another), there is war and everyone is having a crappy time, but hey, all that happened five times in the last hundred years or so already.

The hand of the king was killed? Well, so were five of the last seven hands.

A Targaryen may come, lay waste to all the armies of the realm and be crowned? Well, that already happened in the field of fire, and they had Targaryens for a while, until they ran out of dragons.

The Ironmen may conquer the north? Well, they already had conquered it a couple centuries ago, and then they lost it.

And so on: any of the payoffs of the book series has already happened, some of it more than once. So, what's special about this time around?

Does the author have a plan, something up his sleeve that's going to be a shock? I don't know, but the tricks are starting to get repetitive.

What would happen if, after seven books, it turns out that there's nothing special?

It's Too Earth-Like

The five kingdoms. Scotland, England, Wales, Ireland and which one? Isle of Man? Because, come on. There's these people who are almost exactly Mongols, except they have bells in their hair. There's the pseudo-viking, the pseudo-scots, the ersatz-irish, the fake-italians, the I-can't-believe-it's-not-chinese and so on.

There are knights, whose armour is exactly medieval armour. There's the seafaring raiders, on their longships. Etcetera, etcetera, et-freaking-cetera. It's like whenever the author needs to add an "exotic" character, he just throws a dart at the map, then another, creates a mix 80% one, 20% the other, makes up some silly ortography rule for names, and that's it.

The Magic is Lazy

So, dragons. And of course, dragons create magic (you can see how lots of magical gizmos start working since the dragons came).

So, let's make magic everything. Want to have legendary swords? Then they are made of Valyrian steel. That's magical steel, which is why it seems to never need sharpening. That's why you can have family heirloom swords. Because they are magical.

And there's a magical door, made of magical wood. The magical wood comes, of course, from magical trees.

And there's fake magical swords, made by real eastern magic. And there's magical assassins. And magical coins, magical candles. And so on, and so forth. You can't paint yourself into corners when you can count on there being a magical paintbrush that lays down paint that doesn't stain the magical shoes of the painters of the magical land of Paintheria, whose names always have a double laryngeal consonant in the middle.

More is More is More is Less

The first book manages to tell roughly a (earth) year of story. The fourth and fifth, together because they happen simultaneously, cover perhaps three months. And there are characters we have not seen since book three, when they were just about to say something. We are currently entering the third book waiting to know what the maiden of Tarth said at that moment.

There are books that are about one character, there are those that are about a dozen, there are those that are about one hundred. None of the latter is any good. The story keeps expanding and slowing down. At this step, all of book seven is going to be about a single day in the lifes of 50 first-person characters, and each one will describe their breakfast, before we unexpectedly get promised (very soon now) an eight book which will cover their post-breakfast craps and clear every question we may have had about the subject.

Fan Service

You, who know what was in the pies served in the feast at Winterfell in volume 5, you are being spoonfed that kind of thing to make you feel smart and knowledgeable. If you don't know what was in that pie... well, YOU MISSED IT.

And how is it a good idea to write three pages that (if you have a good memory) shout what was in that pie, when it's a story about a third-line and fourth-line characters whose names noone will remember?

Well, it's a good idea because it's fan service, and fans love being served. But it's a cynical, calculating move. You are being served bad pie there, fans.

So, Are the Books Good?

They are awesome. I can't wait for the sixth volume. George RR Martin, here's my money. Tell me a story.

Syndicated 2013-03-09 21:43:11 from Lateral Opinion

Twitter Off

A week ago, I took a decision I had not seen coming. I shut down comments on this blog unless the post was technical. Because I could not stand some of the comments anymore. I said "comments down for a month, and then I'll see if I miss them".

Well, so far I don't, as you can see by this post having comments disabled.

Today, I am removing the comment track of my life. I an shutting down my twitter account. Some automatic posts will go out, but I am not reading it and am not notified of anything. Again, it's "twitter down for a month, and then I'll see if I miss it΅.

Hopefully I will not.

Syndicated 2013-03-09 12:39:38 from Lateral Opinion

Python Trick: the Fundict (or the Diction)

Suppose you have made the choice in the past of exposing a dictionary as part of an object's interface. So, people are doing things like:

object.data[foo]['bar']

And now you want people to not have to specify foo because it can be obtained from somewhere else. In fact, what you want now is to expose something like this:

object.data(bar, foo='foo')

Here's an idea on how to do that without breaking the old code:

class fundict(dict):
    def __call__(self, bar, foo='foo'):
        return self[foo][bar]

That's a dictionary that's also a callable, and thus indistinguishable from a function. A function-dictionary. A fundict. And of couse, you could also do it the other way around, and implement a function that works as a dictionary. A dictionary-function, a diction. But since that's more work, I used this one.

Syndicated 2013-03-08 18:13:41 from Lateral Opinion

Twitter Card Support in Nikola

This feature for Nikola was implemented by @amokleben, and now, if you ask twitter your site can have it too.

What are Twitter Cards? Did you notice that for some sites, when you click on tweets that have links, you get a small preview of the content? Well, that's a twitter card.

This still needs a little improvement to support the richer "media" cards, but it does work:

http://direct.ralsina.com.ar/galleries/random/twitter-card.png

You don't have to do anything in your site, but setting the "description" metadata to your posts helps make this more accurate (and it also works for google+)

Syndicated 2013-03-05 06:31:57 from Lateral Opinion

Nikola 5.4 is out!

I am thrilled to announce the release of version 5.4 of Nikola, a static site/blog generator

Here's the (incomplete!) changelog for this release [1]:

Features

  • Twitter Card / Open Graph support.
  • Smart math support
  • New soundcould directive
  • Custom "read more" links
  • Better time display, timezone support
  • Better doit integration (Issue #151)
  • Make the whole listings folder browsable (Issue #128)
  • New GZIP_FILES/GZIP_EXTENSIONS options to create gzipped copies of some files (Issue #348)
  • New optional path parameter to new_post command.
  • Wordpress importer: option to not download files
  • Wordpress importer: option to squash newlines
  • Separated BLOG_URL into SITE_URL and BASE_URL
  • Added DISABLED_PLUGINS option (Issue #354)

Bugfixes

  • Added missing </div> in default theme templates.
  • Wordpress import: Description is left empty if no description is found.
  • When running the build command it is now possible to get help.
  • Load jQuery before bootstrap in JS bundle (Issue #327)
  • Generate valid HTML5 for redirects (Issue #276)
  • Fixed "nikola check"
  • Fixed internationalized RSS links
  • Make commands that need to be run in a site fail gracefully (Issue #342)
  • Use localized links on lxml fixer
  • Redirections created during the import from wordpress are now written to conf.py
  • Stop parsing metadata in post file on first blank line
  • Metadata handling cleanups by Tordek
  • Fixed blockquote font size inconsistency
  • Wordpress Import: Do not break indentation (issue #189)
  • Make things work even if SITE_URL has a path (Fix #307)
[1]There are also some extra bits of documentation, and a awesome beta theme called "site-reveal" based on bootstrap and reveal.js!

Syndicated 2013-03-04 18:40:24 from Lateral Opinion

691 older entries...

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!