Skip to main content

Ralsina.Me — Roberto Alsina's website

Standalone Search in Nikola

This has been in the mas­ter branch of Niko­la for a while but on­ly now have I tried to ful­ly in­te­grate it, and pol­ish all (most) of the rough edges.

By de­fault, Niko­la comes with sup­port for search forms us­ing Google and Duck­duck­go. Some peo­ple dis­ap­prove of them for dif­fer­ent rea­sons [1] so there was a re­quest about sup­port­ing a stand­alone search en­gine.

The best of breed of those things seems to be Tipue so that's what I sup­port­ed.

To use this, you need to en­able a plug­in, and do some con­fig­u­ra­tion 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 = """
<span class="navbar-form pull-left">
<input type="text" id="tipue_search_input">
</span>"""

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 de­mo site for you to try!

I would not rec­om­mend do­ing this for a big site, since it may load a mul­ti­-megabyte javascript file when you search, but for small to medi­um sites, it may be ok.

Unfortunate Phrases by Famous People

Like this one:

When your coun­try is at risk, ev­ery­thing is al­lowed, ex­cept not de­fend­ing it.

—José de San Martín

For non-ar­gen­tini­an read­er­s, imag­ine if that was said by a com­bi­na­tion Wash­ing­ton/Lin­coln lev­el fig­ure fa­mous for lead­ing three coun­tries to get rid of the spaniards and al­so for a list of ad­vices for young ladies, whose bi­og­ra­phy is ti­tled "The saint with a sword".

So, any­way, he said that. And that phrase is bad, bad, bad, un­for­tu­nate and hor­ri­ble.

It's that bad be­cause while a nice slo­gan to ral­ly farm­ers in­to be­com­ing sol­diers in the army of a na­tion that does­n't quite ex­ist yet, it's aw­ful ad­vice for peo­ple who live in an ac­tu­al na­tion, with ac­tu­al laws, an ac­tu­al army, and peo­ple who wor­ship what­ev­er crap you hap­pened to say, José.

It starts with the flaky premise "when your coun­try is at risk" which means too lit­tle, or too much, de­pend­ing on just how much you need an ex­cuse to do some­thing hor­ri­ble.

If you re­al­ly want to be a bad per­son, I am sure you can con­vince your­self that gays, im­mi­grants, for­eign­er­s, mus­lim­s, jew­s, the young are all a dan­ger to your coun­try, some­how. You just need to stretch "dan­ger" a lit­tle or maybe push "y­our coun­try" some­what.

And once you jumped that hur­dle, and you are con­vinced your "coun­try" is "at risk", why, then you can do any­thing. Un­sur­pris­ing­ly this stupid line is of­ten framed in mil­i­tary of­fices, and is a tired trope in mil­i­tary speech­es.

I quite like José de San Martín. This quote, how­ev­er, is un­for­tu­nate.

Doing Your Homework, With Style

As usu­al in all pro­gram­ming list­s, ev­ery once in a while some­one will post a ques­tion in the Python Ar­genti­na list which is ob­vi­ous­ly his home­work. To han­dle that there are two schools of thought.

  1. Telling the stu­­dent how to do it is help­ing them cheat.

  2. Telling the stu­­dent how to do it is teach­ing him.

I tend more to­wards 1) but I think I have dis­cov­ered a mid­dle road:

1.5) Tell the stu­dent a so­lu­tion that's more com­pli­cat­ed than the prob­lem.

That way, if he fig­ures out the so­lu­tion, he has done the work, and if he does­n't fig­ure it out, it's go­ing to be so ob­vi­ous­ly be­yond his skill the teach­er will nev­er ac­cept it as an an­swer.

As an ex­am­ple, here's the prob­lem for which help was re­quest­ed:

Giv­en an un­sort­ed list of two-let­ter el­e­ments (une low­er­case, one up­per­case), for ex­am­ple:

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

Sort it by these cri­te­ri­a:

  1. Cre­ate sub­sets ac­cord­ing to the up­per­case let­ter, and sort them by the num­ber of mem­bers in as­cend­ing or­der, like this:

    ['fH', 'mS', 'aS', 'fC', 'hC', 'iC', 'jD', 'bD', 'eD', 'mD']
  2. Then sort each sub­set in as­cend­ing or­der of the low­er­case let­ter, like this:

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

Ig­nor­ing that the prob­lem is not cor­rect­ly writ­ten (there are at least two ways to read it, prob­a­bly more), I pro­posed this so­lu­tion, which re­quires 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.


Contents © 2000-2023 Roberto Alsina