Joho the Blogtech Archives - Joho the Blog

February 1, 2017

How to fix the WordFence wordfence-waf.php problem

My site has been down while I’ve tried to figure out (i.e., google someone else’s solution) to a crash caused by WordFence, an excellent utility that, ironically, protects your WordPress blog from various maladies.

The problem is severe: Users of your blog see naught but an error message of this form:

Fatal error: Unknown: Failed opening required ‘/home/dezi3014/public_html/wordfence-waf.php’ (include_path=’…/usr/lib/php /usr/local/lib/php’) in Unknown on line 0

The exact path will vary, but the meaning is the same. It is looking for a file that doesn’t exist. You’ll see the same message when you try to open your WordPress site as administrator. You’ll see it even when you manually uninstall WordPress by logging into your host and deleting the wordfence folder from the wp-content/plugins folder

If you look inside the wordfence-waf.php file (which is in whatever folder you’ve installed WordPress into), it warns you that “Before removing this file, please verify the PHP ini setting `auto_prepend_file` does not point to this.”

Helpful, except my php.ini file doesn’t have any reference to this. (I use as my host.) Some easy googling disclosed that the command to look for the file may not be in php.ini, but may be in .htaccess or .user.ini instead. And now you have to find those files.

At least for me, the .user.ini file is in the main folder into which you’ve installed WordPress. In fact, the only line in that file was the one that has the “auto_prepend_file” command. Remove that line and you have your site back.

I assume all of this is too obvious to write about for technically competent people. This post is for the rest of us.

1 Comment »

November 11, 2015

Unlocking Keynote's hidden frames

For some reason, Apple Keynote continues to ship with many more frames than it lets you use. (Frames are called Picture Frames when you click on the Border dropdown menu in the Format panel.) You can get Keynote to list these hidden frames if you’re willing to mess around with a file that might break Keynote.

Please nod your head to indicate that you’ve read and understood the above warning.

The first thing to do is to find the hidden files. For Keynote 6.6 (the latest version), they’re here:


To get there you have to select Keynote in your Applications folder and right-click on it, or do what you have to in order to get the popup menu. Choose “Show Package Contents” and navigate to the Frames folder.

Screen capture of frames UI

In that folder is a file named FrameInspectorLayoutInfo.plist. Make a copy of it as a backup and put it some place safe.

Nod your head to indicate that you have done that. I mean it.

Open the original of that file in a text editor of your choice. (If you’re comfortable editing plists in Xcode, use that. It’s easier.) This is an XML file that lists all the frames that will show up when you choose Picture Frame from the Border dropdown. (To see them, you have to click the tiny triangle to the right of the thumbnail view Keynote provides of the Picture Frame you’ve chosen.)

You can see the available frames in the Frames folder in Finder where you found the file you’re currently editing. To add a frame, you add it to the list called “Asset Scales” that is the first half of the file, and you add it again to the list called “Display Order” that is the second half. But you add it differently in each.

Asset Scales expects an entry of this form:

<key>Spiralbook Creme</key>

Please note that I DO NOT KNOW WHAT THAT SECOND LINE MEANS. So I’ve just been copy-pasting it and replacing the name of the frame. It does not work for some frames (e.g., Venetian 3), which results in a blank spot in the menu of available frames…but if you click on that blank space, for some of them you get the frame anyway. In the sample file I’m providing, I have not included any frames with that problem. (Asset Scales probably specifies how to display the thumbnail version of the frame. It just doesn’t work for all of them, and I don’t know why.)

The Display Order list does what it sounds like: it controls the order of the layout of the thumbnails you can choose from. It does not have to be the same as the order of the frames in the Asset Scales list. It expects entries in this form:

<string>Spiralbook Creme</string>

Make a typo and you’ll have a blank spot where a thumbnail is supposed to be, and that blank spot won’t do anything.

Now save the file; it will likely ask you for permission first. Reload Keynote. Enjoy your new frames.

I’m posting a version of the replacement file here. I’ve only added about half of the frames so far because I’m lazy. I’ll add more over time.

Nod your head if you agree not to blame me for screwing up your Mac.

1 Comment »

June 3, 2015

[liveblog] Walter Bender

Walter Bender of SugarLabs begins by saying “What I’m all about is tools.” “The character of tools shapes what you can do.” He’s an advocate of “software libre” that lets the user be the shaper. That brings responsibility, which Walter wants to celebrate.

NOTE: Live-blogging. Getting things wrong. Missing points. Omitting key information. Introducing artificial choppiness. Over-emphasizing small matters. Paraphrasing badly. Not running a spellpchecker. Mangling other people’s ideas and words. You are warned, people.

He’s going to talk about

He goes back to Papert and Cynthia Solomon who in the late 1960s invented Logo. Fifty years ago. Then Jobs and Gates gave us babysitting: sw was there to be used, not an environment for creating ideas. You have to be given the tools and the knowledge.

In 1971, Papert and Solomon wrote “Twenty things you can do with software.” Walter today is going to give us a sense of the breadth of things you can do with software:

  • Using Turtle Blocks to draw interesting shapes, or create a paint program or paint with noise or attach pen size to time. “Once it belongs to you, you’re responsible for it it. And then it has to be cool, because who wants to be responsible for something that’s not cool?”

  • Challenges and puzzles

  • Add sensors, cameras, etc., create aa burglar alarm that photos the burglar

  • measure gravitational acceleration

  • Continent game written by a third grader

  • Build a robot

  • Model math

  • Collaborate across the network in a multimedia chat program

You can even extend the language. You can export your program into another programming language. A child wrote an extension to the language to download maps.

Turtle Blocks tries to make the learning visible to the learner — statistics about what the learner is doing, etc.

It’s got to be easy enough that you’ll try it, but it has to be hard if you’re going to learn. Many tools have low floors to enable easy entry but they also have low ceilings.

“Debugging is the greatest oppportunity for learning in the 21st century.” (Walter ties this idea to Cynthia Solomon.)

What motivates people: autonomy, a sense of mastery, and having a sense of purpose.

1 Comment »

[liveblog] Renee Hobbs on teachers as creators

Renee Hobbs from the Harrington School of Comm and Media is giving a talk about teachers as makers.

NOTE: Live-blogging. Getting things wrong. Missing points. Omitting key information. Introducing artificial choppiness. Over-emphasizing small matters. Paraphrasing badly. Not running a spellpchecker. Mangling other people’s ideas and words. You are warned, people.

The myth of the digital native has hurt teachers and students alike. Students come into classrooms feeling superior. Teachers think the students already know how to use tech.

The concept of literacy is changing. It means being able to go out in the world and do something. That means educators who have to learn concepts like open access, multitasking, transmediation, identity, curation, play. We have to think about who owns our data, how our community is represented, addiction, displacement, and propaganda. And there are more and more “stakeholders.”

There’s a big opportunity to connect culture and the classroom. E.g. minecraft. E.g., analyzing the news. Vital to make connections between school and the world. Popular culture is an important tool for connecting and relevancy. We need to make the “stand and deliver” method obsolete.

There is an art to creating a digital literacy learning environment. Renee has encountered several archetypes:

Teacher 2.0 helps students use media and tech to connect with and learn from others as networked digital citizens. Another teacher is a “spirit guide”: help students use media to support their social and emotional well-being.

So Renee’s group developed a “horoscope”: questions that show what sort of teacher you are, eg., trendsetter, taste-maker, watchdog. (see, etc.

When teachers become media creators, they gain confidence. It’s important for them to learn how to use the relevant tools. E.g., a couple of teachers made a video about “how to solve a maht problem.” Another made a short video of children helping someone across the street. Another used Screencast-o-matic to capture interaction with a google doc to share a lesson plan. The teachers eventually got more playful and fun.

As teachers became more comfortable as media creators, they were better able to connect to students as creators.

“The same way that music is not in the piano, learning is not in the device.”

1 Comment »

[liveblog] Jeremy Roschelle

Jeremy Roschelle is at Stanford Research leading the Center for Innovative Research in Cyberlearning ( is going to talk about cyber-learning. But first he asks to take a deep breath and reimagine learning.

He shows images of places of learning. “What tech we think is good for leaning depends on what we think learning looks like.” Therefore, we need to imagine learning, not tech.

To advance education we need to advance both the science of deep learning and tech.

Jeremy studied with and was inspired by Seymour Pappert.

Learning sciences teach us some principles:

  • Learning is social, and we must design supports for collaboration

  • Learning is multi-representational: it’s important to onnect stories and pictures, and connect the everyday and the symbolic, and enable children to see the meaning among these

  • Learning is in a situation: Take advantage of the setting, the people, the physical world, not only the tech


August 17, 2014

fadeOut, fadeIn jQuery-style

Time for another in my series of occasional posts over-explaining simple programming tasks that took me longer to figure out than they should have.

Let’s say you’re writing a bit of JavaScript and want to fade the text of a component out, change the text, and fade it in. Assume you’re using jQuery to handle the fades. Assume that the component has an ID of “fader” and you want its initial text of “First” to be replaced by the text “Second.” Ok?

Here’s the simple HTML:

<div id="fader">First</div>

With jQuery, you fade an element out by first selecting the particular element. which you can do by putting its ID in quotes and prefixing it with a #: $("#fader"). Then you tell that element what method you want to execute, which in this case is the jQuery “fadeOut” command, with a duration expressed in microsecondsmilliseconds. Put ’em together and you get the simple-but-powerful jQuery statement: $("#fader").fadeOut(500);. Likewise for the fadeIn command.

If you’re me, the first thing you’ll try will be:


function fadeMe(){









Click here to give it a try on the following sample text:


That’s not right. At least in my browser (Chrome). Instead of fading out “First” and fading in “Second,” the word “Second” fades out and then in. Presumably that’s because Javascript isn’t waiting for jQuery to complete the fadeout before moving to the instruction to substitute “Second” for “First” as the element’s text.

So here’s a way that works. (Note that I’m not saying it’s the best or right way. If it’s worse than that, if it’s actually the wrong way, please leave a comment and I’ll link to it at the top of his post. Thanks!)


function fadeMe(){


$(“#fader”).fadeOut(500, function(){









Click here to to try it on the text below:


The difference is that the second way adds a function to the jQuery’s fadeOut command that is invoked only after the fadeOut is completed. That function changes the text of the element and fades it in.

(Click here to reset both examples.)

(PS: I created the tables for the code by pasting it in here.)

Be the first to comment »

February 19, 2013

What’s not ok even with the door closed

Sarah Parmenter has posted about just how ugly it gets for women in tech. She recounts a horrifying story about how as a speaker at a tech conference she was methodically assaulted online. I want to believe that this was a rare and random act, but apparently it happens more than we know because it’s not something generally the victims want to get yet more publicity about.

Thanks to the rise of feminism, the change in behavioral norms over the past 50 years has eliminated many of the superficial, public expressions of misogyny. Not all, of course, but in the circles that I’ve moved in, the change has been noticeable. There are many fewer casual male expressions of discomfort around women, many fewer belittling or sexually objectifying comments. That’s good, but it doesn’t tell us if private expressions have changed, and, more important, how thoroughly the disempowering assumptions and structures are being undone. (And, yes, I know that I must certainly be blind to my own pernicious assumptions.)

For example, I remember in the late 1990s going on a media call to the Boston Globe with a group of male developers with whom I worked. The reporter had some cutting questions about the utility of the software and about competitive threats. The five of us walked quietly back to our car, but as soon as the door was closed, the guys had a good time dismissing the editor’s comments because “she must be on the rag.” Also, she was attractive and several of the lads expressed a desire to relieve her of the stress that brought her to under-appreciate our offering. Needless to say, not only were the editor’s comments perceptive and accurate, had they come from a man we would have taken them as a conversational challenge to which we would have risen, rather than as dismissing them as carping by a bitchy, hormonally-prejudiced girl.

These were young techie men who I’m sure sincerely supported gender equality policies. The degree of their discomfort and, yes, loathing of women had never manifested itself before. This was not acceptable banter, any more than, say, racist comments would have been. Yet when the door was closed and it was just us guys, it might as well have been 1950. I was shocked.

I have to say that I haven’t seen that sort of behavior among men with the doors closed since then. I don’t know if that incident was anomalous, or if I happen to travel in circles that don’t tolerate that type of sexism, or at least don’t tolerate the overt display of it. Or maybe as I’ve become old, my presence drives all the boyish “fun” out of the room — you can’t really talk about girls when Dad is in the room. I’d like to think we’ve changed. But it’s so hard to know what goes on behind closed doors.

Until someone opens them, even at personal cost. So, thank you, Sarah.


October 30, 2012

[beginner2beginner] How to add a row to MySQL unless it already exists

This is really basic, but it drove me crazy. Suppose you want to add a row of data to a MySQL database, but not if there’s already an entry in it with the essence of that data. For example, suppose you have a table of notes and the titles they’re clustered under, and don’t want to allow the same note to appear more than once for any particular title. Assume also that that table is also recording an identifier of which book the note is about.

Here’s a SQL statement that works (line breaks don’t matter):

VALUES('fiction', '1234','5678');

With the exception of the mysterious “IGNORE” (see below), this is a straightforward command that inserts a row into the table “playlistentries” with a series of values (‘fiction’, ‘1234’,’5678′) mapped to the series of fields (title, noteid, bookid). If there’s already a row with those title and noteid values, the table will be left unchanged. Otherwise, a new row will be added.

But, this will not work unless you set up your MySQL table so that it has a unique key based on the fields you’re testing for (title and noteid in this example). That way when you go to insert a row that has an already-existing title and noteid, it will be automatically rejected. The “IGNORE” in the SQL statement means it will be rejected without creating an error message that just gets in the way.

To set up your table so that it has the right unique key, use a SQL statement like this:

ALTER TABLE playlistentries 
ADD UNIQUE KEY noteidtitle (noteid,title(100))

This tells MySQL to create a unique key (named “noteidtitle”) based on the fields noteid and title. The “(100)” is there to tell MySQL that it should only look at the first 100 characters of the title field; if you’ve set up your table with that field as “text,” you’ll get an error unless you put a limit on it. A hundred characters is probably 75 more than I need.

Note also that you only run the “alter table” command once in the lifetime of your database.

Finally, please note that there is a high probability that what I’m telling you is wildly inefficient, non-robust, and suboptimal. On a scale of 1-100, I am about 3 points past raw beginner. But these commands work for me, and I am assuming as always that if you’re reading this, you are an amateur like me engaged in some small project designed primarily for your own use. Improvements and do-overs will be gladly accepted.


August 22, 2012

When php will only read itself

Some little apps I’ve written for myself over the years refused to work on a Mac with Lion that I’ve started using at work. The problem was that any php invoked via Ajax would return only itself — that is, the return value would be the lines of the php script itself. This is not helpful.

I poked around a lot on the Net and couldn’t find anything relevant. The closest was the observation that this can happen if you begin your PHP scripts with just a <? instead of <?php, which seems awfully persnickety. Unfortunately, my scripts didn’t begin with the abbreviated form.

After getting some help by posting at, it seemed that the machines that my scripts have worked on have PHP v.5.3.8, whereas my Lion computer for some reason was at PHP 5.3.1. So, I upgraded the php to 5.4. This page has easy instructions for doing so: (If you want to know what version of PHP you have, in a terminal window type “php -v”.)

I’m not 100% sure that it was the PHP upgrade that did it and not some random other change or a change in the phase of the moon. But it’s working. And if you’ve been having the same weird problem with PHP, maybe it will work for you.

Be the first to comment »

July 27, 2012

Importing HTML into Google Docs spreadsheets

Rick Klau points [g+] to a feature of Google Docs spreadsheets I didn’t know about (although I’m far from a spreadsheet maven): It can automatically include a table from any HTML document accessible on the Web. It turns out it can also include the contents of lists.

It’s not the most intuitive feature. Into a cell you type:


Except you put in the HTML page’s url instead of [URL], “table” or “list” instead of [query], and which the number of the tables or list you have in mind instead of [index]. For example:


gets the first list (ul or ol) on Joho The Blog (this page you’re reading), which turns out to be the one on the left called “Other Stuff.” If you ask for 2 instead of 1, you’ll get my blogroll.

Or, to use Rick’s more useful example:


That imports AccuWeather’s table of weather for Anchorage (where Rick is headed for vacation.)

The data updates every time you open the spreadsheet.

ImportCVS does the same for CVS data. And Kingsley Idehen explains how you can update your spreadsheet with Linked Open Data by going through SPARQL. (SPARQL lets you query a database for linked data.) (Yes, it’s over my head.)

Wouldn’t it be useful to be able to import a single element into a Google spreadsheet, even if it’s not in a list or a table? For example, suppose I want to get the headline of the first posting at, say, That element has an id of “article-1”. (I know this because I looked at the source.) So, why not let me specify the url and the id, and plop the contents into a cell in the spreadsheet? Or suppose I want the content of one particular cell of a table?

No, we’re never satisfied.


Two seconds after I pressed the “Publish” button, Rick Klau responded to my questions on the Google Plus thread where he talks about this feature. He suggests importXML for grabbing an item by its id. And to get a frozen copy of the data, copy and paste it. He also points to a post from 2007 about these features. (Oh, yeah, you can trust Joho to stay on top of the news!) In fact, that post gives an example of how to obtain the latest headline from the NYT:

=GoogleReader (“”, “items title”, “false”, 1)

It still works. Cool!!


Next Page »