Logic in templates
A ticket last month wanted a line of text under the Add to Cart button that the client could set per product in the admin, something like “Usually ships in 2 days.”
That’s an ordinary ticket here. A lot of them are about 80% front end and 20% back end. The 80 is mine: the markup, where it sits next to the swatches, how it wraps on a phone, and what happens to it between Luma’s mobile-only styles and its desktop-only ones. The 20 is getting the words out of the admin and onto the page.
For my first year here I built the 80 around placeholder text and handed the 20 to a back-end developer.
<div class="product-ship-note">
<!-- TODO: pull this from a product attribute -->
Usually ships in 2 days
</div>
They’d make the attribute, swap my sentence for the real value, and send it back. Then I’d review their change to my template and it was always tiny, a few lines that were mostly the markup I’d already written. It started to seem like too small a thing to be handing to somebody else. The ticket would sit in their queue for a day or two waiting on about five minutes of their time.
Front end, that’s me
I’d have told you a year ago that I don’t write PHP. I said it in a way that sounded like a boundary instead of a gap. “Front end, that’s me, I do the part you can see.”
It even held up for a while. A year ago this month, a ticket to make a dollar sign smaller ended with me writing a ticket for a back-end developer because the $ came out of a PHP method and I didn’t write PHP. At the time that felt like the line doing its job.
But every template I’ve touched here is a .phtml file. That’s not a file that “has PHP in it.” It is PHP. The file I’d been handing off was a PHP file I’d already been editing all year while telling people I didn’t write the language it was written in.
It was always tiny
Here’s the template once I’d done the 20 myself and it had been through a review.
<?php $_note = $block->getProduct()->getShipNote(); ?>
<?php if ($_note): ?>
<div class="product-ship-note"><?php echo $block->escapeHtml($_note) ?></div>
<?php endif; ?>
$block is the object the layout hands the template, and on a product page it knows which product it’s drawing. Nobody wrote a method called getShipNote(). Magento turns get plus the name of any attribute into a lookup of that attribute, so a field called ship_note in the admin comes out as getShipNote() in the template. The if is there so a product with nothing in the field doesn’t get an empty box.
The field itself is an attribute. It goes in an upgrade script because an attribute made by hand in the admin only exists in the database you made it in.
The script is a PHP class whose constructor asks for an EavSetupFactory and gets one, by a mechanism I’m told is called dependency injection and am currently taking on faith. It runs when somebody bumps a version number in an XML file and then runs bin/magento setup:upgrade. I copied the shape of it from one of our other modules and changed the names, which I’m guessing is how most people’s first one goes.
Doing it badly with witnesses
The language was never the hard part. PHP is not hard. It was hard to be visibly mediocre at something in a building where several people do it well and get paid for it.
I dreaded asking a question that I figured had a one-word answer and so I sat on questions for days at a time. I wrote things that worked and were embarrassing and hoped nobody would open the file.
The first one I sent for review came back from one of the back-end developers with a comment that started “this works, and here’s what I’d do instead.” I’d printed the attribute straight into the page. They’d wrap it in escapeHtml() because the text comes from a field somebody types into, and one day somebody will type a < into it.
It said “this works” first and not “this is wrong.” That sounds like a small difference and it was the whole thing for me. It meant that my code was allowed to exist while being improvable. I don’t think a person can learn in front of an audience on any other terms.
I wrote a whole post two Decembers ago about the badly done version being the only one on offer. It turns out I only believed that about side projects, where the audience is nobody. Believing it about work in a repo other people read is a much bigger ask, and I was nowhere near it a year ago.
Where the line is now
I do still have a line and I think it’s a real one this time. I’ll add a field and put it on the page. I stay out of anything that decides what the database does and I stay out of the caching layer. When a ticket needs either, I hand that part over without any feeling about it at all.
This time I’ve looked at those and decided, and that’s what a boundary is. The old line was just the edge of what I’d looked at. I’d been calling it a wall with all the confidence of somebody who has never once gone and checked.
Free with purchase
Oddly enough, the language turned out to be the side effect.
I understand data a bit now in a way I didn’t before. Not PHP specifically.
Every field on a product page is an attribute somebody defined, stored somewhere, and loaded by something. “Can the client edit this” is a question with an actual answer instead of a request I pass along. I’d have nodded along to that a year ago but I couldn’t have found you an example of it.
I’ve also lost the ability to say “that’s a back end problem” as though it were a routing instruction. Sometimes it really is. But I’d been saying it about anything that happened before the HTML existed, which I think covers most of what decides whether the page is any good.
And in a small practical way it made me better at the job I actually have. I can tell now whether the awkward thing I’m being asked to do in a template is awkward because I’m doing it wrong or awkward because the data is arriving in a shape nobody picked on purpose. Those need two completely different conversations and I used to have the first one every time.
None of it was a plan and I think about that a lot. If I could tell myself one thing a year ago, it wouldn’t be “learn PHP.” I’d tell myself that the label on your job describes what you did last year instead of fencing off what you’re allowed to touch. I was using mine as both, and the second use was costing me things I’d never have counted.
The fastest learning I’ve done this year had nothing to do with courses, which I’ve taken plenty of and gotten real value out of. It came from needing one specific thing on an ordinary day for a real reason, with somebody waiting on me.
Motivation was never my problem and neither was structure. Proximity was the problem, and a job fixes proximity in a way I haven’t found anything else to match. I still wouldn’t call myself a PHP developer. I notice that’s a modesty thing now instead of a factual one though, which I guess says something on its own.