A client came to me today with an error they were getting when
trying to create a new post in their WordPress admin panel. This is
what they were seeing:
Warning: Illegal string offset 'type' in
wp-content/themes/thesis/lib/admin/options_post.php on line 150
and they could not get around it to edit or write new posts.
After some digging (and some print_r statements) I found the bug and
corrected it by changing the offending line 150 from:
`
if (($meta_field['type']['type'] == 'checkbox') && is_array($meta_field['type']['options']))
{
`
to:
`
if ((is_array($meta_field['type'])) && ($meta_field['type']['type']
== 'checkbox') && is_array($meta_field['type']['options'])) {
```
The problem occurs because newer versions of PHP correctly give an
error when the ['type'] field contains a value instead of an array.
Thesis folks: Please incorporate the above fix!
A short tutorial.
Let's run through creating a Perl web application with Mojolicious
and styling by Zurb Foundation. We will
create this first as a full "application" and then as a "Lite" version.
Installing (Perlbrew and) Mojolicious
While perlbrew is not strictly required, the latest versions of Perl
have a number of features and optomizations that help Mojolicious.
There are two ways to install all this: Globally for all users (I
recommend this if you are administering the entire server, and want to
keep just one set of software) or in your home directory (best if you
share a server).
*Installing in your home directory *Following the instructions here
[perlbrew.pl], install Perlbrew into your home directory: something
like this:
\curl -L http://install.perlbrew.pl | bash
nice perlbrew -j 5 install perl-5.20.2
Note the 'nice' (to reduce impact on a running system) and the "-j
5" (to use up to five concurrent compilation threads) − although on
an active server, you might want to just use the default single
thread. Observe the final output of perlbrew: You will almost
certainly have to edit ~/.bash_profile
as it suggests, logout,
and then log back in to enable the perlbrew
command.
Now permanently switch to the new Perl, and install Mojolicious:
perlbrew switch perl-5.20.2
sudo sh -c "curl get.mojolicio.us | sh"
*Installing globally *Assuming a brand new machine (possibly a Linode
virtual machine), first we install the latest Mojolicious under
/local/bin ... if you don't do this as root this way, I recommend
you probably get a cpanminus version somewhere in your user home
directory.
sudo sh -c "curl get.mojolicio.us | sh"
Creating a Mojo "app"
OK now we can go into a working directory somewhere and type:
mojo generate app Test
which will create an entire tree of default files under the
subdirectory 'test' for a program called 'Test.'
At this point you should be able to start your example program:
cd Test
morbo script/test
and view the default text at http://localhost:3000
Adding Zurb Foundation to your "app"
Next we get the latest Foundation distribution from their website.
At the time of writing, this gave me foundation-5.3.1.zip. Create a
subdirectory called foundation
under the public directory and unzip
into there. This will create subdirectories css
and js
among a few
others.
wget <em>latest_foundation_link_from_above
</em>cd public
mkdir foundation
cd foundation
unzip ../../foundation*.zip
cd .. <em># back to Mojo project's public</em>
We are going to leave those files in a pristine tree so we can replace
them later, and create symbolics links to them. Note the slightly
curious use of relative paths in the symbolic links below. The multiple
../
are needed because symlinks are relative to the destination file,
not the directory where our shell happens to be when they are created.
Also, if only the destination directory and not a filename is given,
the destination filename is copied from the source (linked-to) file.
# Assuming the latest Foundation framework code
# is downloaded into the 'foundation' directory,
# and that we are currently in the 'public'
# directory in your generated mojo application,
# here we make symlinks from our document root
# into there, only for the files we actually use.
mkdir css
mkdir -p js/vendor
ln -s ../foundation/css/normalize.css css/
ln -s ../foundation/css/foundation.min.css css/
ln -s ../foundation/js/foundation.min.js js/
ln -s ../../foundation/js/vendor/jquery.js js/vendor/
ln -s ../../foundation/js/vendor/modernizr.js js/vendor/
It is worth a reminder that the syntax here is:
<tt>ln -s</tt> <em><small>{source (real file)} {destination (new link name)}</small></em>
Building the HTML for Foundation
Starting with the basic HTML from here:
http://foundation.zurb.com/docs/css.html
We copy some of the code from the original default.html.ep and create
the new templates/layouts/zurbish.html.ep as follows:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- Zurb Foundation stuff -->
<meta name="viewport" content=
"width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/foundation.min.css">
<script src="js/vendor/modernizr.js"></script>
<!-- end Zurb -->
<title><%= title %></title>
</head>
<body>
<script src="js/vendor/jquery.js"></script>
<script src="js/foundation.min.js"></script>
<script>
$(document).foundation();
</script>
<%= content %>
</body>
</html>
Then in templates/example/welcome.html.ep we change the content to be
as follows:
% layout 'zurbish';
% title 'Welcome';
<h2><%= $msg %></h2>
This page was generated from the template "templates/example/welcome.html.ep"
and the layout "templates/layouts/zurbish.html.ep",
<a href="<%== url_for %>">click here</a> to reload the page or
<a href="/index.html">here</a> to move forward to a static page.
<div class="row">
<div class="small-2 columns">2 columns</div>
<div class="small-10 columns">10 columns</div>
</div>
<div class="row">
<div class="small-3 columns">3 columns</div>
<div class="small-9 columns">9 columns</div>
</div>
Now, http://localhost:3000
should give you the example text in a
very, very basic Foundation based layout. From here, you might want to
follow one of the excellent Mojolicious tutorials out there. Here is
Zurb's official guide to the Grid,
for example.
Also useful is this from "Zurb U"
which explains the small/medium/large grids. The one-line gist is:
If you don't specify small-# to a column, Foundation will assume
you mean "go full-width on small screens."
As a "Lite App"
For simplicity, here is basically the same program as a single file, in
the form of a boilerplate Mojolicious "Lite app":
#!/usr/bin/env perl
use Mojolicious::Lite;
get '/' => sub {
my $c = shift;
$c->render('index',
msg => 'Welcome to the Mojolicious real-time web framework!');
};
app->start;
__DATA__
@@ index.html.ep
% layout 'zurb';
% title 'Welcome';
<div class="row">
<h2><%= $msg %></h2>
<div class="small-2 columns">2 columns</div>
<div class="small-10 columns">10 columns</div>
</div>
<div class="row">
<div class="small-3 columns">3 columns</div>
<div class="small-9 columns">9 columns</div>
</div>
@@ layouts/zurb.html.ep
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- Zurb Foundation stuff -->
<meta name="viewport" content=
"width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/foundation.min.css">
<script src="js/vendor/modernizr.js"></script>
<!-- end Zurb -->
<title><%= title %></title>
</head>
<body>
<script src="js/vendor/jquery.js"></script>
<script src="js/foundation.min.js"></script>
<script>
$(document).foundation();
</script>
<%= content %>
</body>
</html>
If you save the above as example.pl
for example, then the command
morbo example.pl
should permit you to view the generated one-page site at http://localhost:3000
Next steps
In the next installment,
we will see how to better use Mojo's template system with Foundation.
Additional Resources
What I learned at Digital Techniques, Inc. Burlington, MA 1984-1989
From 1984 to 1988, I was a co-op student at DTI of Burlington, Mass.,
whilst I attended Northeastern University. This was an excellent little
company that made software and hardware well ahead of the industry, but
which suffered from a marketplace that changed faster than anticipated
and not in the way that was envisioned. This resulted in a bankruptcy
and reorganization. The company's excellent technical legacy was
carried through the Touchcom line which was acquired by today's G4S in
2008 (2012 press release).
The below commentary is my personal perspective, a quarter century
later.
Back to 1984
The Touchcom system had an over-engineered chassis, suitable for
practically military grade. This might have been an asset at Kappy's
installations, but everywhere else it pushed expense and limited
flexibility. Industrial-strength CPU and controller cards were used
with a custom-built graphics display card (GDC) and other custom
components. The use of the industrial STD bus, while possibly an asset
in the early 1980s, became an albatross even by 1985.
Software was based on industry-standard MS-DOS but not commodity IBM PC
compatible, slowing development and also limiting increased capability.
Low-level software was wisely (for the time) separated into an
assembly-language coded "TCOS" but coding in a higher level language
like C would have offered 90%+ of the speed and much better expansion
potential at faster/lower cost. TCOS was poorly documented even to
internal systems coders, greatly diminishing the utility of the
approach. Many high-level applications reworked TCOS functionality in
far slower scripting code.
Mid-level software used the innovative Magic/L language from Loki
Engineering. Magic/L was a threaded language (like FORTH) inside, with
a coding style reminiscent of Pascal and the later Perl language. Upon
this base was built "TNT" (The New Touchtext) which interacted with
TCOS to provide interactive graphics with an event-driven interaction
handler loop, presaging Microsoft Windows and JavaScript by many years.
When opportunity to redesign the hardware came, instead of using
standard components and building just a custom GDC, which could have
been an opportunity to expand market for DTI's advanced graphics ...
instead, a single, massive, all-in-one CPU/I-O-controller/video card
was built as an expansion card (!) for the IBM PC system bus. This then
necessitated an even more ununusal chassis. The amount of money and
time spent on this curious exercise, which did little to make the
system more functional or marketable, astonishes me even today.
To be sure, by the time I graduated Northeastern in 1988 and left DTI
as a contractor in 1989, all these shortcomings were in the process of
being rectified, but the window of opportunity had been lost.
Some Lessons:
In both hardware and software, follow the UNIX, and LEGO, philosophy of
building modules. Build and make money on the smallest possible unique
element where you add value ("As small as possible, but no smaller" --
[after] Einstein). Leverage other people's investment wherever you can,
by following and building onto standards, and by creative re-use of
common components.
Michael Ossman brings us the handiest little set of network
administrator tools you can fit in
your mini-screwdriver set. With one standard Ethernet cable, a
straight-through coupler, and a few homebrew adapters, you will have:
straight-through ethernet cable:
crossover ethernet cable:
ethernet - coupler - crossover
modem cable:
DB9/RJ45 - ethernet - DB9/RJ45
null modem cable:
DB9/RJ45 - ethernet - coupler - crossover - DB9/RJ45
Cisco console cable:
DB9/RJ45 - ethernet - coupler - Cisco adapter
This set is easily expandable with a loopback (which will work on both
Ethernet and RS-232, also useful for testing distant connectors) and
one-way sniffers.
Read the rest of the story.
Message passing.
Investigate 0mq as a light(er-)
weight alternative to rabbitmq.
Configuration Management
Slaughter. It's
pure Perl so there's no new microlanguage to learn.
A Perl Web framework
http://mojolicio.us/ looks worthy of exploring.
Perlbrew
I was amazed at how well perlbrew works for
maintaining user-specific copies of Perl. No more worrying that a
system upgrade will break your application... no more problems with
different versions of a module between users.