Paul M. Jones

Don't listen to the crowd, they say "jump."

A PSR-7 Web Router Implementation, and Bookdown Documentation

From the Aura blog:

Our first 3.x package is now available for review, a PSR-7 implementation of Aura.Router. It includes some feature upgrades such as custom rules and more powerful route definitions.

...

On a side note, the package documentation uses Bookdown for its documentation. You can see the generated documentation here. Bookdown allows us to keep documentation sources in each library repository. We can then collect them all into a single “book” on the Aura site using a bookdown.json file with remote “content” elements.

Read the rest at the Aura blog.



Separate The User Interface Repository From The Core Application Repository

tl;dr: Keep the core application (“model”, “domain”) code repository separate from the user interface (“controller/view”, “action/responder”) code repository; use a dependency manager in the user-interface repo to bring in the core-application repo.


Nihal Sahu asked on Twitter, “How do you ‘personally’ go about building an application? What Structure?” This post is my longer-than-140-characters response.

Obviously I’m a fan of Action-Domain-Responder as a pattern for web-based user interfaces. (ADR treats the request/response cycle itself as a user interface. The HTML/CSS/JS/etc that goes into the HTTP body is just one part of the presentation half of the user interface; ADR reminds us that the HTTP headers are part of the presentation, too.)

But ADR, and MVC, and the other user-interface patterns – they are not an application architecture in and of themselves. The “Domain” in ADR and the “Model” in MVC are just entry points into the underlying core of the overall application architecture. In a way, the “Action/Responder” and “Controller/View” portions of the UI are not the big deal in the application; the big deal is the underlying core. That’s where the real work happens.

With that in mind, one first thinks the right approach would be to separate the User Interface from the Core Application. This is obvious and uncontroversial; separation of concerns is a central tenet of good architecture.

What might be controversial is my extended advice regarding that approach. I don’t suggest a merely “logical” separation of concerns so that Action/Controller classes don’t have Domain/Model code in them. I suggest a “physical” separation. In other words:

Separate the User Interface repository from the Core Application repository.

Yes, I mean that you should have two code repositories for your application. Let’s explore that idea for a minute.

The first repository, the Core Application one, contains no user-interface code at all. No HTTP, no standard input/output, nothing. It expects to receive input in an interface-independent way, and it delivers output in an interface-independent way. Note that it receives the input. It has to be sent to the Core Application in some way, not read from the interface (no superglobals!). The injected input could be via method parameters, a plain old PHP array, an input object provided by the Core Application, a Command object provided by the Core application, etc. Likewise, the output could be via anything provided by the Core Application, such as a Model object, a Domain Payload, or something else. It is completely independent from any user interface code and can be tested on its own.

The other repository, the User Interface one, contains your “Action/Responder” or “Controller/View” (or “Command/Stdout”) code. There is no business logic at all. All it does it reformat the user input to something the Core Application will recognize, pass it to the Core Application, and receive back some output from the Core Application, which it reformats for presentation to the user.

But if the two repositores are “physically” separated, how can the User Interface get access to the Core Application? Composer becomes your best friend in this case. In the User Interface codebase, add "require": { "project-name/core-application": "dev-develop" } to composer.json. Issue composer update and voila: your Core Application is now available to the User Interface. The User Interface depends on the Core Applicatiion, but the Core Application has no dependency on the User Interface.

What’s great about keeping the repositories fully separated from each other is that it enforces developer discipline. It becomes difficult to put Core Application code in the User Interface code. Any attempts to do so are immediately obvious, and everyone watching can see it happening. It becomes harder to justify to yourself “I’ll add it just this one time” (and thus keeping off that particular slippery slope).

The tradeoff is that you now have to coordinate changes across two code repos. Breaks in the Core Application will break the User Interface. The disconnection can be a positive overall, since you can version the Core Application separately from the User Interface, but in practice it does mean you have to be more attentive to change management.

One more thing about keeping the User Interface “physically” separate from the User Interface in this way is that you start thinking differently about frameworks. I have begun to think that our vocabulary for describing frameworks in PHP land is insufficiently varied. MVC and ADR do not describe “application frameworks” – they might describe User Interface frameworks, but there’s no word for Core Application frameworks. Maybe they need their own separate framework term.



Aura 3 Plans

From the Aura blog:

  • The Past

    • Aura 1.x framework packages will see no new releases, and may be archived.

    • Aura 1.x library packages are near the end of active development; to prevent orphaning and end-of-life, ownership and authority over them they may be transferred to interested parties.

  • The Present

    • Aura 2.x packages that are currently stable will remain the center of development attention, with some modifications to Composer and PHPUnit support files, and with added testing on PHP 7.

    • Aura 2.x packages that are not currently stable will not see stable 2.x releases; they will become 3.x candidate packages.

  • The Future

    • Aura 3.x packages will target PHP 5.6, and additionally test on PHP 7.

    • Aura 3.x library packages will be allowed to depend on interface packages, though not other implementation packages.

    • Aura 3.x will not provide a framework under the Aura name, although the 2.x framework should be able to use 3.x components. Frameworks of Aura packages may be provided as separate projects.

    • Aura 3.x and later packages will have independent major version release cycles.

Read the entire post here.


Using Aura.Html with League\Plates

Aura has its own native PHP template package, Aura.View, a direct descendant of Savant and Solar_View, as well as a cousin to Zend_View.

The v1 Aura.View package used to include a helper system. Once we realized that there was no reason to tie the helper system directly to the view system, we released the helpers as a standalone Aura.Html package. This means the helpers can be used in any PHP presentation code, framework-based or otherwise.

As an example, let’s try integrating the helpers with Plates, a relative newcomer in the native PHP templating world. Plates allows you to register functions with its template engine, which means we can pull individual helpers out of Aura.Html and drop them into Plates, like so:

<?php
$plates = new League\Plates\Engine('/path/to/templates');
$helper = (new Aura\Html\HelperLocatorFactory())->newInstance();

$plates->registerFunction('anchor',     $helper->get('anchor'));
$plates->registerFunction('anchorRaw',  $helper->get('anchorRaw'));
$plates->registerFunction('base',       $helper->get('base'));
$plates->registerFunction('form',       $helper->get('form'));
$plates->registerFunction('img',        $helper->get('img'));
$plates->registerFunction('input',      $helper->get('input'));
$plates->registerFunction('label',      $helper->get('label'));
$plates->registerFunction('links',      $helper->get('links'));
$plates->registerFunction('metas',      $helper->get('metas'));
$plates->registerFunction('ol',         $helper->get('ol'));
$plates->registerFunction('scripts',    $helper->get('scripts'));
$plates->registerFunction('styles',     $helper->get('styles'));
$plates->registerFunction('tag',        $helper->get('tag'));
$plates->registerFunction('title',      $helper->get('title'));
$plates->registerFunction('ul',         $helper->get('ul'));
?>

Now you can use the tag helpers and form-building helpers from Aura.Html in your Plates templates. For example, if your Plates template looks like this …

<html>
<head>
<?= $this->title('My Title'); ?>
</head>
<body>
<p>Try out <?= $this->anchor(
    'https://github.com/auraphp/Aura.Html',
    'Aura.Html'
); ?>
with <?= $this->anchor(
    'http://platesphp.com',
    'Plates'
); ?> !</p>
</body>
</html>

… it will render to:

<html>
<head>
    <title>My Title</title>
</head>
<body>
<p>Try out <a href="https://github.com/auraphp/Aura.Html">Aura.Html</a>
with <a href="http://platesphp.com">Plates</a> !</p>
</body>
</html>

Try out Aura.Html today, and see how much you like it with your output system of choice. (We’re partial to Aura.View for that task, but then, we would be.)

UPDATE: As usual, Hari KT is ahead of the curve with his post on this same topic from a year ago: http://harikt.com/blog/2014/05/13/extending-plates-with-aura-html-helpers/.

UPDATE 2: Someone asked how easy it is to use Aura.Html with Aura.View. It's 3-lines-easy: see https://github.com/auraphp/Aura.View#custom-helper-managers.




A New Book About The N+1 Problem, and an Update to MLAPHP

I’ll have a new book finished and ready for you soon: Solving the N+1 Problem in PHP. Although I have written and spoken about the N+1 problem several times over the past few years, this book is an extended disstertation on the topic.

Describing the N+1 problem is one thing, and talking about the solutions in the abstract yet another. But how to diagnose and discover the problem, as well as refactoring strategies to resolve N+1 problems in your codebase? Those are something else, and they are what the new book provides, similar to the strategies I presented in Modernizing Legacy Applications in PHP. At about 40 pages of narrative and code, in many ways the new N+1 book serves as a topic-specific add-on to MLAPHP.

Speaking of which, MLAPHP is getting an update! The update is nothing extensive, mostly typo fixes and a couple of added details, all from attentive and interested readers. Current owners will receive the update for free.

So when will they be completed? Monday. And there’s a special deal involved for the week they’re finished.

MLAPHP is just about a year old, so to celebrate this new book, if you purchase both MLAPHP and the N+1 book as a bundle next week, they will each be about 50% off. That’s a total of $23.99 $22.99 (suggested $39.99 $28.99) for both books, with a 45-day money-back guarantee backed by Leanpub.

After the sale week, they’ll go back to their normal prices, so this is your chance to get a bigger bang for your buck. Of course, the new N+1 book is only $5.99 (suggested $7.99), so it’s not exactly a bank-breaker in the first place.

More updates when the new book and the update are finalized!

UPDATE (Fri 20 Mar): The bundle is now available at https://leanpub.com/b/mlasn1php. Go get it while you can!


I'm not anti-intellectual; I'm anti-intelligentsia.

One kind of “anti-intellectualism” is opposition to “intellectuals” considered as an interest group or social class in the Marxian sense – what Russian writers called the intelligentsia. The only more specific term I can think of for this is anti-intelligentsianism, an ugly coinage which will have to do for the duration of this essay.

...

The intelligentsia has displayed a consistent political pattern over the last 150 years: believing in its own intellectual and moral superiority, it has sought a leading role in politics, promoting a vision of itself as benign philosopher-kings who can steer society to virtue, equality, and fulfillment.

The vehicles of this belief have been many. At its worst, it has led the intelligentsia to endorse and propagandize for totalizing systems like Communism, which the intelligentsia conceived could be guided to good ends in its use of power by – who else? – intellectuals. It is forgotten, but true, that before World War II many intellectuals were attracted to Fascism for the same reason. In this way much of the intelligentsia of the 20th century became accomplices in and apologists for the most hideous mass murders in human history.

Via The Varieties of Anti-Intellectualism, worth reading in its entirety. (it gives voice to part of what I mean when I say "It's not enough to be smart; you have to actually know things.")


Everything You Think You Know About The Crusades Is Wrong

It is generally thought that Christians attacked Muslims without provocation to seize their lands and forcibly convert them. The Crusaders were Europe’s lacklands and ne’er-do-wells, who marched against the infidels out of blind zealotry and a desire for booty and land. As such, the Crusades betrayed Christianity itself. They transformed “turn the other cheek” into “kill them all; God will know his own.”

Every word of this is wrong.

via Inventing the Crusades by Thomas F. Madden.


Bookdown: DocBook-Like HTML Output From Markdown

From bookdown.io:

Bookdown generates DocBook-like HTML output using Markdown and JSON files instead of XML.

Bookdown is especially well-suited for publishing project documentation to > GitHub Pages.

Features include:

  • Automatic table-of-contents generation as index pages at each hierarchy level

  • Custom index-page titles via JSON configuration

  • Automatic numbering of page headings

  • Automatic previous/next/up navigation headers and footers

  • Multi-page hierarchical output

  • Loading of remote content files via HTTP

  • Templated output for theming

  • Overridable page processing, especially for rendering

Bookdown can be used as a static site generator, or as a way to publish static pages as a subdirectory in an existing site.

Yes, I know, there’s a ton of static site generators for PHP out there already. Sculpin seems to be the big one (hi Beau!) but it’s not specifically for documentation. Then there’s Couscous (hi Matthieu!), which is for documentation, but it’s not DocBook-like documentation.

By “DocBook-like”, I mean (among other things) numbered headers, auto-generated tables-of-contents on their own pages, hierarchical multi-page presentation, and the next/previous/up linking at the top and bottom of pages. Look at the Solar documentation sites for a better idea; the content on those pages was generated with DocBook.

And frankly, look at the dependency listings on those two projects (Scuplin, Couscous). They’re rather extensive. It that a bad thing? No, but it’s not my speed. I think we we all know at this point that I’m about reducing dependencies as much as possible, and those are just too much for me.

Also: I can’t stand YAML. I don’t like YAML embedded in pages, and I don’t like YAML config files. I much prefer JSON, and I don’t want to add YAML frontmatter on Markdown pages.

So: Bookdown. This scratches my particular itch, with very few dependencies.

Bookdown, although it can be used as a site generator, is only incidentally a site generator. What it really is is a page generator, with the idea that you can integrate the pages into any other site you want.

Additionally, Bookdown allows you to pull content from remote locations. This is especially interesting to me because of the decoupled nature of Aura libraries. I would like very much to keep the manual documentation on each library in the same repo as that library, then publish each alone, and as part of a collection, without having to copy files around. Bookdown remote content should allow for that.

I’m happy with the architecture as well. It took two weekends of experimenting, and then almost exactly a week of dedicated development, to build Bookdown.

The library is fully separated from the project. That means you can either run it as a project on its own, or integrate the core library into your own project and glue its services and commands into your own work.

Everything uses dependency injection through an application-specific container which helps to keep the concerns well-separated. Everything uses factories and builders, which helps to enable the dependency injection.

All the underlying processes are decoupled from each other, which should make it easy to replace them with custom processes. For example, the ConversionProcess currently uses CommonMark, but I find it easy to imagine end-users replacing that with Textile, ReStructuredText, or even a combination of conversions that examines the filename extension.

Finally, the code style is a little bit of a departure for me as well. I have previously used $snake_case variables, but I tried on purpose to use $camelCase instead, and it was not a hard switch to make. Camel-case seems more popular these days, so I may bow to common convention from now on.

I really enjoyed putting this together. It’s something I’ve wanted to see in PHP land for a long time, and I finally got the opportunity and inclination. Take Bookdown out for a test drive, see how you like it, and please feel free to provide constructive feedback!



The Formula For Anti-Capitalist Concern-Trolling

Then economists ... commenced worrying about, to name a few of the pessimisms concerning “capitalism” they discerned: greed, alienation, racial impurity, workers’ lack of bargaining strength, workers’ bad taste in consumption, immigration of lesser breeds, monopoly, unemployment, business cycles, increasing returns, externalities, under-consumption, monopolistic competition, separation of ownership from control, lack of planning, post-War stagnation, investment spillovers, unbalanced growth, dual labor markets, capital insufficiency, peasant irrationality, capital-market imperfections, public choice, missing markets, informational asymmetry, third-world exploitation, advertising, regulatory capture, free riding, low-level traps, middle-level traps, path dependency, lack of competitiveness, consumerism, consumption externalities, irrationality, hyperbolic discounting, too big to fail, environmental degradation, underpaying of care, slower growth, and more.

... [The formula is this:] First, discover or rediscover a necessary condition for perfect competition or a perfect world (in Piketty’s case, for example, a more perfect equality of income).

Then assert without evidence but with suitable mathematical ornamentation that the condition might be imperfectly realized or the world might not develop in a perfect way.

Then conclude with a flourish that “capitalism” is doomed unless experts intervene with a sweet use of the monopoly of violence in government to implement anti-trust against malefactors of great wealth, or subsidies to diminishing-returns industries, or foreign aid to perfectly honest governments, or money for obviously infant industries, or the nudging of sadly childlike consumers, or, Piketty says, a tax on inequality-causing capital worldwide.

From McCloskey in a long, but inspired and genius, review of Piketty; lightly edited for brevity from the original at http://ejpe.org/pdf/7-2-art-4.pdf.

UPDATE (also lightly edited):

One begins to suspect that the typical leftist starts with a root conviction that capitalism is seriously defective. The conviction is acquired at age 16 when he discovers poverty but has no intellectual tools to understand its source.

Then the lifelong “good social democrat”, in order to support the now deep-rooted conviction, looks around when he has become a professional economist for any qualitative indication that in some imagined world the conviction would be true, without bothering to attach numbers drawn from our own world.

It is the utopianism of good-hearted leftward folk who say, “Surely this wretched society, in which some people are richer and more powerful than others, can be greatly improved. We can do much, much better!” The utopianism springs from the logic of stage theories, conceived in the eighteenth century as a tool with which to fight traditional society.