<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
    <title>Tamas Erdelyi – Posts</title>
    <link>https://terdelyi.co.uk/posts/</link>
    <description>Articles on software development, PHP, open source, and the craft of building software for the web.</description>
    <language>en-gb</language>
    <lastBuildDate>Mon, 13 Jul 2026 10:20:16 +0000</lastBuildDate>
    <atom:link href="https://terdelyi.co.uk/feed.xml" rel="self" type="application/rss+xml"/>
    <item>
        <title>The Tailwind paradox</title>
        <link>https://terdelyi.co.uk/posts/the-tailwind-paradox/</link>
        <guid>https://terdelyi.co.uk/posts/the-tailwind-paradox/</guid>
        <pubDate>Tue, 13 Jan 2026 00:00:00 +0000</pubDate>
        <description>Why one of the most popular open-source tools is still struggling to grow and sustain a business, how AI is changing developer products, and the challenges of building a company around software that’s essentially free.</description>
        <content:encoded><![CDATA[<p>This term could easily go into tech history books after one of the most successful open source web dev packages is still struggling to find a reliable maintenance model after 6 years. Maybe building a tech company around a CSS utility framework was too big a chunk? Should open source projects necessarily grow into teams or billion dollar businesses? I'm not trying to investigate the reasons it failed or might yet succeed. At least from what we see today, this is certainly not the beginning of the end, but rather fine-tuning of the business model. I'm also not trying to recommend the right direction for the product, but I thought it would be the right time to take a look at a couple of angles: what open source means nowadays, and how hard it is to build a product when your main offering is basically free.</p>
<h2>The bad news</h2>
<p>In January 2026, two pieces of news started to cause some panic in my bubble. First, a Laracasts employee posted about his layoff, then the next day a Tailwind Labs engineer. Which was later also confirmed by one of the key members of the framework, Adam Wathan in a comment under a Pull Request, and later in more detail in his podcast. Because it's the beginning of the year, a lot of business owners look back at year and run forecasts for the following to set the direction.</p>
<p>They both mentioned AI as a dominant force of this change, but not that because AI models will replace software engineers. In Laracasts' case, since AI tools became popular, people have started to watch fewer videos about how to build things, as they can now an AI agent to do so in plain English. For Tailwind, the causes are similar: models can write components quickly, and because they're trained on documentations, their visitor numbers have <a href="https://github.com/tailwindlabs/tailwindcss.com/pull/2388#issuecomment-3717222957">declined by 40%</a>. A very similar drop to <a href="https://blog.pragmaticengineer.com/stack-overflow-is-almost-dead/">what Stack Overflow has to suffer nowadays</a>. Just to clarify the numbers in both layoffs: we're talking about 3 of 4 engineers at Tailwind and <a href="https://x.com/simonswiss/status/2008519159211311430">only one staff member at Laracasts</a>, which means we're certainly not talking about the scale of what Microsoft or Amazon done recently.</p>
<p>Last year GitHub reported almost <a href="https://github.blog/news-insights/octoverse/octoverse-a-new-developer-joins-github-every-second-as-ai-leads-typescript-to-1/">395 million open source repositories</a>, with tens of millions of new projects created annually, while the <a href="https://ademait.es/papers/msr22-ademait-survival.pdf">survival rate is less than 50%</a>. Many projects are short-lived or abandoned early, only 15–20% show ongoing maintenance. A small fraction are financially sponsored and thousands receive <a href="https://github.blog/news-insights/company-news/announcing-github-secure-open-source-fund">GitHub Sponsors support</a>, but that's a tiny share relative to the total number of projects.</p>
<p>Maintaining open source projects can be exhausting. The internet is full of annoyed people, they're always demanding, suggesting and get pissed when things don't go in the same direction as they want to see. You go to sleep with one bug and you wake up to 10 more. Or just a bunch of PRs as part of Hacktoberfest where people trying to get free merch by changing your README file. Or security issues where a &quot;good samaritan&quot; messages you privately, but threatening you paying some ransom unless they go public with a backdoor. In more positive cases you might just switch off half of the internet. I'm seriously not surprised so many people give up, because it's exhausting both timewise and mentally.</p>
<h2>The good news</h2>
<p>Tailwind CSS is a very popular project. However, as Adam posted on GitHub, financially that's still not enough to build a successful product company around it. A close example where this was possible is Laravel, which was already in good shape with Envoyer and Forge before <a href="https://laravel-news.com/laravel-raises-57-million-series-a">they raised $57 million Series A</a>.</p>
<p>His frustration is absolutely valid. He raised his concerns about the future in several places over the year, with no real direction in sight.  Although since he posted his podcast episode on 7th January, they have already grown to 29 partners, 4 ambassadors and 26+ supporters, which totals in at least $168k MRR as today, over $1 million annually. It sounds amazing, but I'd rather wait and check these numbers again a year later to see how many of these individuals and companies were just doing &quot;karma farming&quot;.</p>
<h2>What's next?</h2>
<h3>Giving up</h3>
<p>If things don't improve permanently they might abandon the project and make millions of developers instantly upset and disappointed around the world. I can't accept that this is the outcome Adam is personally looking for, however he's frustrated sometimes. They could also leave the repo unmaintained, allowing people to fork it, and slowly new branches would emerge from the ashes of Tailwind, but that would cause awkward fragmentation problems. At the moment, Tailwind feels like a common good, which is great for open source, but also sad when an idea that might be the biggest achievement of your life doesn't generate enough to chase even bigger dreams. A lot of entrepreneurs, writers, and creators are stuck at this stage, and I can imagine how frustrating it can be.</p>
<h3>More funding</h3>
<p>My second thought was that people would realise the situation is serious and that a lot of donations would start coming in over the next few weeks (and I was right!). Maybe more big companies will also realise this and allocate a percentage of their profit to fund the development for the coming years. But let's be real: this is only a temporary solution.</p>
<h3>New products</h3>
<p>They could introduce a new marketplace for Tailwind plugins and components, similar to what ShadCDN is doing, but the direction the software industry already suggest we might not need components in the future, since AI models can come up with their own in minutes. They're trained on documentation, blog posts and articles about Tailwind which would certainly raise proprietary questions if we were talking about paid product. But being open source puts this area of laws into a &quot;fair use&quot; grey zone. While opinionated frameworks and plugins are useful and their existence results in higher quality LLM generated code (since they're giving predefined boundaries to the context) I don't believe that theme marketplaces have a long future.</p>
<p>A natural move could be to introduce Tailwind-related paid products or official plugins, just like WordPress did with Automattic and its paid plugins, or as I've already mentioned, Laravel with Forge, Cloud, Nightwatch, and a bunch of other services. An official Tailwind-built AI service or model that can generate intuitive and modern web designs or themes using Tailwind components would be an instant hit and could massively transform the theme market. Don't forget: they also have both authors of the Refactoring UI book in the team. Although after the layoff, it won't be easy to build these products with a smaller team.</p>
<h3>Acquisition</h3>
<p>My last theory is that a big tech company or startup (someone like Vercel) suddenly appears and gives Adam and the co-owners a bag of money, takes over the burden of maintenance, maybe full ownership through and acquisition, and they either stay on the board or fully exit. It might sound like a failure, but I actually think that would be a very beneficial outcome for Adam and his mental health. I don't think he should be ashamed for even a minute, considering the accomplishments he's achieved over the past decade (not just for Tailwind), and I'm sure that if he were able to drop this ballast and start from scratch, he would eventually come up with a fresh new idea.</p>
<h2>Final thoughts</h2>
<p>Whatever happens, I think the main conclusion here is that if you're a developer working whether in a team or alone, and your work or products are heavily based on free, open source packages, frameworks or tools, don't forget to support them when you are able to afford it. It doesn't necessarily have to be money. It could be a PR for a bug fix or improving their documentation, but giving back something should be an obvious move since the first open source package appeared.</p>
<p>This is one of the main reasons that starting this year, <a href="https://opencollective.com/phpfoundation">I'm officially backing the PHP Foundation as an individual</a>.</p>
]]></content:encoded>
    </item>
    <item>
        <title>How to break into tech for free without a degree</title>
        <link>https://terdelyi.co.uk/posts/how-to-break-in-tech-for-free-without-a-degree/</link>
        <guid>https://terdelyi.co.uk/posts/how-to-break-in-tech-for-free-without-a-degree/</guid>
        <pubDate>Thu, 12 Sep 2024 00:00:00 +0000</pubDate>
        <description>PHP South West in Bristol recently hosted a really valuable Q&amp;A, offering insights into the changing dynamics of bootcamps in today’s job market. Spoiler alert: there is still value in learning coding today, despite the dominance of AI.</description>
        <content:encoded><![CDATA[<p>In September, at <a href="https://www.meetup.com/php-sw/">PHP South West</a> in Bristol there was a very insightful and informative Q&amp;A about bootcamps with Mike Oram from IO Academy. We’ve probably all heard about bootcamps, which help you learn new skills at a fast pace, especially when you’re looking to change careers or need to gain knowledge in specific areas. There are thousands of companies around the world offering bootcamps on different topics and with varying levels of quality, for a certain fee. Most of them also guarantee that you’ll land a job within a few months after completing the program.</p>
<p>This was the reality before the global pandemic, which completely changed the game. After COVID-19 the UK government invested heavily in bootcamps to help upskill people during uncertain times. However, this led to higher dropout rates in bootcamp courses, as many signed up for free and weren’t truly committed since they weren’t paying anything. Hiring also shrank to basic levels, and the job market still hasn’t fully recovered today.</p>
<p>The pandemic accelerated digital adoption, but economic challenges — including inflation, rising interest rates, and supply chain issues — caused a decline in consumer spending and mass layoffs, particularly in 2022 and early 2023. As a result, hiring decreased significantly for bootcamp graduates. Therefore, when starting a bootcamp, don’t expect to land a job immediately, and be sure to consider the financial commitment. It may be wise to prioritise free courses over paid ones.</p>
<p>With the arrival of ChatGPT, Google Gemini, Anthropic’s Claude, and Facebook’s Llama, generative AIs have also transformed the job market. The positive impact is that many companies are investing in AI technology and hiring more people to explore its potential. However, many of these companies are unnecessarily chasing the &quot;holy grail&quot; by forcing AI into their products, focusing on trends rather than applying AI to the right use cases. Trends come and go, and we’ll see in a few years if AI was truly worth the bet. As of today, 85% of AI projects fail, with a lot of them <a href="https://www.youtube.com/watch?v=d7DtiMzMBdU">sadly being scams designed to attract investment</a> or profit from preorders before disappearing with the money or at least hesitating to refund.</p>
<p>AI-driven automation has rapidly taken over routine jobs as well. Therefore, it’s important to consider how much it affects bootcamps and junior developers. Using AI as a developer shouldn’t be an inexcusable sin, regardless of what the same people who back in the days were skeptical about the need for a global network of interconnected computers, but, like anything else, it should be used wisely. Mike mentioned that they teach bootcampers in a smart way. It’s not forbidden, but they encourage using AI for code generation only when the developer has already written something similar before. If you ask AI to generate code for something you don’t understand, you might end up shipping insecure or inefficient results due to hallucination and the AI’s tendency to produce responses aimed at satisfying you rather than being accurate. AI is still not advanced enough to steal people’s jobs, and it probably never will be (at least not in your life).</p>
<p>I’ve been using Copilot for the past 8 months, and although my experience has been mixed, I’ve found a perfect use case where AI can be really powerful: learning new programming languages. It helps explain what a certain line of code does or provides examples of how to write the same code in different languages or frameworks, which has saved me hundreds of hours spent on Google and reading through manuals. It’s still not something I can blindly trust, but since I’ve mostly worked alone over the past year, it’s been useful for pair programming with a junior-mid level virtual assistant. It has often offered different perspectives on problems that I hadn’t considered. However, for higher-level design architecture decisions, I still recommend reading books on the topic, even if your AI of choice has read and can summarise them. My issue with services that extract key parts of a book is the lack of context. Authors aim to engage readers, and important concepts sometimes require a broader context. Additionally, reading has numerous benefits, such as improving focus, expanding vocabulary, and reducing stress.</p>
<p>If you’re planning to start coding, go to YouTube and check out some introductory videos. Read a few articles in the topic, apply some short and free online courses and see if it’s something you might genuinely be interested in. There are many people who complete coding courses simply because the media has told them that anyone can become a coder and make a lot of money. However, speaking from my own experience as a middle-aged father looking for projects and jobs just to cover my bills and go for holiday once or twice in a year that’s not necessarily true.</p>
<p>Once you’ve gathered all the information and still want to start your journey as a programmer, don’t spend years in school (which I also skipped). Instead, consider enrolling in a free bootcamp and stay curious.</p>
<h2>Where to start?</h2>
<ul>
<li>Find <a href="https://nationalcareers.service.gov.uk/find-a-course/page?courseType=Skills%20Bootcamp&amp;sectors=7">Skill Bootcamps at National Careers</a>.</li>
<li><a href="https://www.coursereport.com">Course Report</a> is like GlassDoor for courses, what’s not on there you should probably avoid it.</li>
<li><a href="https://io-academy.uk">Bootcamp Academy in Bath</a> put a lot of effort to give you up-to-date skills, and they're focusing on the basics of programming rather than languages and frameworks.</li>
<li><a href="https://codebar.io">Codebar.io</a> is a platform for minority group members to learn programming around the UK.</li>
<li><a href="https://www.codecademy.com">Code Academy</a> offers free online courses to test our your interest.</li>
</ul>
]]></content:encoded>
    </item>
    <item>
        <title>If it looks like a duck and quacks like a duck it must be about typing</title>
        <link>https://terdelyi.co.uk/posts/if-it-looks-like-a-duck-weak-and-strong-typing/</link>
        <guid>https://terdelyi.co.uk/posts/if-it-looks-like-a-duck-weak-and-strong-typing/</guid>
        <pubDate>Fri, 15 Sep 2023 00:00:00 +0000</pubDate>
        <description>The debate is back about type systems after a popular JavaScript framework removed TypeScript support from its codebase. Let&#039;s take a look why typing can be important, what is TypeScript and why we shouldn&#039;t dig a grave for Turbo just yet.</description>
        <content:encoded><![CDATA[<p>David Heinemeier Hansson (aka DHH), creator of Ruby on Rails and founder of
37signals <a href="https://world.hey.com/dhh/turbo-8-is-dropping-typescript-70165c01">recently announced</a>, he's removing
TypeScript from <a href="https://turbo.hotwire.dev/">Turbo</a> starting from version 8, which has made him the target of never-ending
mocking regarding typing and software reliability.</p>
<p>Turbo is a JavaScript framework to create progressively enhanced web applications. The way it achieves that is by
capturing every link click and form submission, changes all to AJAX requests, then extracts the <code>body</code> from the
response to replace corresponding parts of the existing page. It does that without affecting the <code>head</code> tag and requiring a full
page reload. Behind the scenes, it also manages the browser's back button functionality and stores the history of full
<code>body</code> contents in a cache. Additionally, Turbo also supports requesting and fetching updates through WebSocket, not just XHR.</p>
<p>Turbo is the heart of the <a href="https://hotwired.dev/">Hotwire framework</a> which contains a couple other frameworks like
Stimulus and Strada to build
native-like Single Page Applications (SPA) without using any progressive frameworks like React or Vue, and all templates are
generated on server-side.</p>
<p>It is the similar technique what <a href="https://laravel-livewire.com/">Laravel LiveWire</a> implemented, which was also heavily inspired by an Elixir module
called <a href="https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html">Phoenix LiveView</a>. Other implementations are also available out there like <a href="https://htmx.org/">htmx</a> or <a href="https://inertiajs.com/">Inertia.js</a>.
Unlike LiveWire, Hotwire doesn't require any backend framework.</p>
<h2>What is TypeScript?</h2>
<p>JavaScript was originally never intended to be a programming language, certainly not for large applications. It was born
as LiveScript, a scripting language thanks to a collaboration between <strong>Netscape</strong> and <strong>Sun Microsystems</strong> to embed Java into
Netscape Navigator in 1995. That's also the reason for its later renaming, because of its syntax similarities to Java. When
the legendary browser
wars began between Netscape and <strong>Microsoft</strong>, the latter reverse-engineered Navigator's interpreter to create their own
variation which they named JScript. A year later, Netscape submitted JavaScript to ECMA International, an
organisation founded to standardise computer systems. The intention was to create a standard which could all
browser
vendors adopt and that finally led to the official release of the
first <a href="https://www.ecma-international.org/publications-and-standards/standards/ecma-262/">ECMAScript specification</a> in
June 1997. JavaScript in
the beginning didn't really have structuring concepts you would normally
find in other programming languages. These deficiencies made very difficult to build reliable large-scale applications.</p>
<p><a href="https://www.typescriptlang.org/">TypeScript</a> is a programming
language <a href="https://hanselminutes.com/340/what-is-typescript-and-why-with-anders-hejlsberg">built on the top of JavaScript</a> (or as they refer themselves a superset of
JavaScript) introduced in 2012 by Microsoft, mainly to resolve those concerns about large-scale development. Aside to
static typing and type checking at compile time, it also introduced classes, generics, visibility, union types, enums, modules and
namespaces which all helped to elevate JavaScript to a higher level. TypeScript code is backward compatible with
JavaScript, which can be compiled into regular JavaScript, then it can be executed in a browser's JS engine or in
server-side runtime environments like Node.js.</p>
<p>Here's an example of a simple TypeScript code:</p>
<pre><code class="language-typescript">class Car implements Vehicle {
    private brand: Brand;
    private model: Model;
    private year: string;

    constructor(brand: Brand, model: Model, year: string) {
        this.brand = brand;
        this.model = model;
        this.year = year;
    }

    getTitle($withYear: boolean = false): string {
        if ($withYear) {
            return `${this.brand.name} ${this.model.name} (${this.year})`;
        }

        return `${this.brand.name} ${this.model.name}`;
    }
}
</code></pre>
<p>You might love or hate TypeScript, but you cannot really find a job where the tech stack doesn't require
TypeScript in pair with JavaScript, weather it is server or client side programming. JavaScript also evolved in the past
decade, and today it has features which were only available in TypeScript before:</p>
<ul>
<li>Class keyword and modules have been introduced in ECMAScript 2015 (ES6)</li>
<li>You can emulate enums using object literals or constants</li>
<li>JSDoc annotations can provide type hints for better tooling</li>
</ul>
<h2>Strong or weak vs. dynamic or static</h2>
<p>Type safety is a feature of a programming language which simply means the language only allows you to perform operations
allowed by a data type. For an example you shouldn't use a method which requires a string on a numeric value. This
permission is checked during type checking which can be static or dynamic. <strong>Dynamically</strong> (or weakly) typed languages
check the types during runtime, meanwhile <strong>statically</strong> (or strong) typed languages usually does the same through compile time. Not
all languages are need to be compiled before runtime (like PHP, Ruby or Python), those are called <strong>interpreted languages</strong>.</p>
<p>JavaScript itself is <strong>weakly typed</strong>, which means its type system is more permissive and allows for implicit type
conversions and late type binding. Type violations might not be caught until runtime which may lead to unexpected
runtime errors. Languages like PHP, Ruby and Perl are all weakly typed.</p>
<p>On the other hand, with <strong>strong typing</strong> every variable and expression has a fixed data type that is determined at
compile-time. Type violations are caught at compile-time, which means that the code must stick to the specified
types, and any mismatch will result in a compilation error. Examples for strongly typed languages are Java, C, Smalltalk
or Pascal. Python however is both strongly and dynamically typed language.</p>
<p>TypeScript is also strongly typed and because it's compatible with JavaScript we can enforce type checks on our code
during compilation. As I've already mentioned PHP is dynamically typed, and we have no options to force type checking. Although,
it offers features like <em>type declarations and type hinting</em> which can check types in runtime if we specifically ask
it to do so by adding <code>declare(strict_types=1)</code>. Static analysis tools like <a href="https://psalm.dev/">Psalm</a> and <a href="https://phpstan.org/">PHPStan</a> can be also very
helpful by going through on our codebase without actually running it and catch possible issues caused by typing. Those
tools can also benefit any additional details specified in PHPDocs, mainly because PHP's native typehints are still not
perfect.</p>
<p>We can compare the previous TypeScript example with a PHP implementation and see the code is very much similar:</p>
<pre><code class="language-php">&lt;?php

declare(strict_types=1);

class Car implements VehicleInterface
{
	public function __construct(
		private Brand $brand,
		private Model $model,
		private string $year,
	){
	}
	
	public function getTitle(bool $withYear = false): string
	{
		if ($withYear) {
		   return &quot;{$this-&gt;brand-&gt;getName()} {$this-&gt;model-&gt;getName()} ({$this-&gt;year})&quot;;	
		}
		
		return &quot;{$this-&gt;brand-&gt;getName()} {$this-&gt;model-&gt;getName()}&quot;;
	}
}

</code></pre>
<p>There are also other ways to work around typing. <strong>Duck typing</strong> is a method of type checking that looks at the structure (properties and methods) and the functional
aspect of the object rather than its name or class. If it walks like a duck and talks like a duck, we treat it like a
duck, even if it's not.</p>
<p>People who prefer dynamically typing generally highlight the <em>flexibility, reusability, faster development speed, and
<a href="https://martinfowler.com/bliki/DynamicTyping.html">a better flow</a>,</em> which were also the same arguments that DHH came
up with in his post. Others favour <em>catching bugs early, ensuring safety, reliability, benefiting from
additional type information in the code and better IDE support</em>, even if compiling is a slower process or strict typing
could affect readability.</p>
<blockquote>
<p>&quot;You don't need static type checking if you have 100% unit test coverage.&quot; by <a href="https://blog.cleancoder.com/uncle-bob/2016/05/01/TypeWars.html">Robert C. Martin</a></p>
</blockquote>
<p>Personally, I believe there isn't a good or bad choice here. <strong>Like many aspects of software engineering, it's about
trade-offs.</strong> Whenever it's possible I always enforce strict typing in PHP and use static analysis as part of
continuous integration, because it helps me recognise what the code accept and what's expected to be the outcome.
However, I cannot really appreciate enough that PHP is dynamically typed language.</p>
]]></content:encoded>
    </item>
    <item>
        <title>Developer&#039;s journey: From novice to expert</title>
        <link>https://terdelyi.co.uk/posts/from-novice-to-expert/</link>
        <guid>https://terdelyi.co.uk/posts/from-novice-to-expert/</guid>
        <pubDate>Thu, 24 Aug 2023 00:00:00 +0000</pubDate>
        <description>Learning programming can be hard–so hard that you might forget why you&#039;re doing it and stuck with the same tools and languages. This is the short story of how I overstepped that boundary.</description>
        <content:encoded><![CDATA[<p>It begins with you being a user. You enjoy the experience, learn the rules, play and relax. Then, sometimes, it
continues with curiosity—to see behind the curtains, eager to modify those rules or create new ones.</p>
<p>Transitioning from your first computer language to own the mindset of an engineer can be difficult, frustrating, and
often a tediously long procedure. You can always find shortcuts, practice through days and nights, but even with the
toughest, most nonsensical parts, you cannot predict when things will click. But eventually, they will.</p>
<p>My journey began with a national program that brought free broadband connectivity to high schools in Hungary. I was so
much mesmerised by the information highway that on some days, I just couldn't go home after my classes. I spent
afternoons  in a lonely basement where we ran the school's web server on an i486, building websites or simply chatting
with unknown  people from around the world. In 1998, I stepped into the era of Netscape Navigator, Hotmail, and various
Telnet applications. I started with HTML, and later, someone showed me how to capture and process POST requests using
Perl.</p>
<p>A couple of years later, PHP 4 arrived into my life, followed by Postgres, MySQL, and my first CMS / framework called
<a href="https://en.wikipedia.org/wiki/TYPO3">Typo3</a>. However, programming was still just a hobby for me. I found more
confidence in designing websites. A decade later, in 2008, I learned a golden rule: <strong>you can't be perfect in
everything.</strong></p>
<p>This is one of the things that companies often misinterpret: the term &quot;full stack&quot;. It doesn't mean you have to be
equally great in frontend, backend, and devops; it means you have the right skills to navigate through the common
obstacles of web development. It means having the ability to build and ship a product or application from scratch, even
if the end result isn't necessarily perfect. Perfection is a programmer's holy grail, something we often strive for it,
but can never reach it. Simply because it doesn't exist. There's no perfect code—only code that is safe to be shipped
because it gets the job done. The evolution of software is a natural part of the process and is equally important as
the personal growth of the person who writes it. More knowledge and experience make you think smarter and faster,
reducing the amount of fear of the unknown.</p>
<p>Returning to my story, I realised the need to specialise. I accepted that I couldn't be equally great in all areas, but
I enjoyed writing HTML and CSS, you know making Photoshop layouts alive, so maybe I could call myself a site builder.</p>
<p>From 2013, my unique skill set was PHP, although I learned it the hard way: fake it until you make it. But it made me
fall in love with backend programming and introduced me to concepts like dependency injection and the repository
pattern. With CodeIgniter, Laravel and Yii, I arrived in a perfect time to be witness of the language's resurrection.
After introducing the PSRs, <a href="https://phptherightway.com">the history of modern PHP</a> evolved rapidly; they even skipped
PHP 6. Later, I was pushed to learn new things about frontend (jQuery, ES6, React, Vue), with detours in mobile and
desktop application development, then SaaS, microservices, CI/CD pipelines, serverless architecture, infrastructure as
code, design patterns, SOLID, DRY, YAGNI, TDD, and BDD—so many things that my brain needed more time understand. Some
started making sense within a month, while others took a year more to click. Today I'm no longer addicted to Laravel,
and I seize every opportunity to try out languages other than PHP.</p>
<p>What I'm trying to tell you through my story is that <strong>you must always remain open and hungry</strong>. Don't stick to one
framework or one language. Learn <em>the basics</em>, variables, loops, control structures, and data structures. Learn from the
<em>mistakes</em> or journeys others have made: design patterns, software paradigms—programming is a flat circle, everything
else are just SDKs and APIs to memorise. Read about <em>algorithms</em>, how to be more effective or improve performance.
There's nothing new under the sun, just better tools which are naturally faster, perhaps a bit shinier, but the
foundations are always remain the same. Some are better suited for the task, while others are less. Invest enough time
in learning everything about your task, inspect any inherited code, then make the best decision about tools,
architecture and approach based on all the information you have.</p>
<p>Prioritise simplicity over complexity, focus on input and output, try, fail, and then try again. Once you've learned
these things, you're no longer just a full stack, ninja or 10x developer. You're a software engineer armed with the
right tools and mindset to do the best you can: <em>write software</em>.</p>
]]></content:encoded>
    </item>
    <item>
        <title>Don&#039;t be OK with spaghetti code</title>
        <link>https://terdelyi.co.uk/posts/dont-be-ok-with-spaghetti-code/</link>
        <guid>https://terdelyi.co.uk/posts/dont-be-ok-with-spaghetti-code/</guid>
        <pubDate>Thu, 10 Aug 2023 00:00:00 +0000</pubDate>
        <description>I received a job description where one sentence instantly caught my attention. That inspired me to share my thoughts about code debt and igniting a culture of code improvement.</description>
        <content:encoded><![CDATA[<p>A few weeks ago, I received a job description through a recruiter and one sentence instantly caught my attention:</p>
<blockquote>
<p>Our app got built on spaghetti code, so need to be ok with that.</p>
</blockquote>
<p>From the top of my head I could think of two reasons why this detail was highlighted:</p>
<ol>
<li>They want to manage your expectations. Most developers hate to work with spaghetti code. The mess is usually the result of unmaintained code debt, frequent changes in features, developers coming and going and deadlines are often tight.</li>
<li>They are looking to hire people with extensive experience (or enough patience), as the readability of a spaghetti code is typically very low. That also comes with a lot of stress and creates the opportunity to introduce new bugs anytime, which in overall can easily lead to burnout.</li>
</ol>
<h2>How to approach spaghetti code?</h2>
<p>First of all, let's call it by its real name: <strong>legacy code</strong>. Obviously, anything you write today will become legacy code tomorrow, but from a codebase perspective, legacy refers to what we inherited and might not be comfortable to work with. It's usually difficult to see where the business logic begins and where it ends, which particularly affects confidence.</p>
<p>Therefore, we need a plan to overcome these challenges and make some preparations about how to tackle any upcoming problems. A proper plan should create enough room for improvement.</p>
<p>Before touching any line of code, you need to have tests first. Not necessarily at the unit level, but at least integration tests to ensure the code is doing whatever it supposed to do. If you're dealing with web applications it can be simple tests running in a headless browser, checking the output, or more programmatic tests to validate certain methods in the background which calculate or generate things are just working fine. Although tests could be hard to write when your code is tightly coupled. If you don't have any tests, certainly don't try to write all in one go, but targeting any main features should be enough.</p>
<p>Once you have tests, you can begin with refactoring. Instead of randomly choosing where to start, let your tests guide you. Think about the parts of your code where writing them were especially challenging - that's your first task!</p>
<aside>
<strong>Quick tip:</strong> Chances are high that your code is indented. When writing tests, start from the outside and work your way inside. When refactoring, start from the inside and work your way out.
</aside>
<h2>The cost of refactoring</h2>
<p>“But how can I sell this to my manager? We don't have time for this. This would take ages, and time is money!” Familiar thoughts? I was in the same shoes at some point in my career.</p>
<p>Understanding the problem of legacy code and recognising it as part of the development process can be extremely difficult from a business perspective. It may seem like you're not generating value and you're just rewriting things that already work. Do you and your manager have full confidence that they are working properly?</p>
<p>If you're logging bugs in JIRA or any ticketing software you should be able to generate a report on these issues could be resolved by rewriting the code from scratch, rather than seeking ways to patch them. What's even more frustrating is that sometimes you could spend considerably more time in reproducing bugs than actually fixing them.</p>
<p>Let's look at another example: have you ever felt like there's a ghost in the machine? Things happen, and you cannot explain where or why? Well, good news, you might have an argument. Inconsistency is the enemy of both developer and business. When all parties understand this, you can make a deal: <strong>start with small steps</strong>. For an example allocate 10% of the main development time to maintenance, then slowly make it a habit and part of your software development process. The same argument applies for writing tests. Without tests, you can only assume that your code works, but you don't have any written proof.</p>
<p>Sadly, this cycle is pretty much never-ending. You might think when finally everything is refactored you can sit back and relax. Of course, your application will continue to generate profit without any further modifications, and you may never need to add new features again. However, eventually, it will be old, obsolete and deprecated. As technology rapidly evolves, it's gradually losing support from the language its written in. Or that third party code (aka dependency) you added to save time will be outdated without a replacement. Then your users will start looking for quicker and more efficient alternatives, and your business will start to lose money.</p>
<p>The break is temporary. It is good for the businesses to slow down a little, generate some easy revenues, and build a passive income for the future. It's also beneficial for developers to catch up, summarise pain points, make plans and decide what's next in line with the business. You can start adding new features on the following day, continue maintaining your code, and forget about making notes in job ads like the one mentioned at the beginning of this post.</p>
<h2>Don't just warn, communicate the plan!</h2>
<p>We can all agree that the level of transparency in that job description is remarkable, but emphasising the interest, moreover a potential decision for the change would be more important.</p>
<p>You want to hire a developer to <strong>maintain your code, not just someone to deal with it</strong>.</p>
<p>With all that in mind let's make a quick revision of the original sentence:</p>
<blockquote>
<p>Our app is built on spaghetti code, but we're dedicated to improving it through refactoring. To achieve these goals, we're looking for a talented and enthusiastic software engineer who is not afraid of challenges.</p>
</blockquote>
<p>And here you are, you have a candidate who's already empowered.</p>
]]></content:encoded>
    </item>
    <item>
        <title>WordPress tip: Searching for a keyword in post titles or meta query values</title>
        <link>https://terdelyi.co.uk/posts/search-for-title-or-meta-values-in-wordpress/</link>
        <guid>https://terdelyi.co.uk/posts/search-for-title-or-meta-values-in-wordpress/</guid>
        <pubDate>Wed, 27 May 2020 00:00:00 +0000</pubDate>
        <description>WordPress is an old school, straightforward CMS, but it also could be a real pain in the ass for common tasks like searching. By default, WP Query searches for keywords which appears in the title and meta values at the same time. You can&#039;t pick one or other. Of course there&#039;s a few workarounds, but I have a dead simple trick for you.</description>
        <content:encoded><![CDATA[<h2>How does searching work in WP Query?</h2>
<p>If you let me to use a strictly MVC term in an event driven system WP Query is basically the router of WordPress. Hidden behind the nice and clean permalinks WordPress loads posts and run search queries through query strings. By using <code>s=</code> in the URL like <code>https://myawesomewpsite.com/?s=Geronimo</code> it will search for posts which has the phrase &quot;Geronimo&quot; in their title, excerpt and content.</p>
<p>You can extend this circle to also search in the <code>wp_postmeta</code> table:</p>
<pre><code class="language-php">&lt;?php
function my_theme_customize_search($query) {
    // Specify the query we want to change: the search in the front-end
    if (! $query-&gt;is_admin() &amp;&amp; $query-&gt;is_main_query() &amp;&amp; $query-&gt;is_search()) {
        // Change some query parameters
        $query-&gt;set( 'posts_per_page', 10 );
        $query-&gt;set( 'post_type', ['page', 'post'] );

        // Search in meta values
        $meta_query_args = array(
            array(
                'key' =&gt; 'battle_cries',
                'compare' =&gt; '=',
                'value' =&gt; $query-&gt;get('s'),
            ),
        );
        $query-&gt;set( 'meta_query', $meta_query_args );
    }
}
add_action( 'pre_get_posts', 'my_theme_customize_search' );
</code></pre>
<p>But the problem is you won't see any results. If you're using <a href="https://querymonitor.com/">debugging tools like Query Monitor</a> you can easily check the generated WHERE clause:</p>
<pre><code class="language-sql">AND (
  (
    (wp_posts.post_title LIKE '%Geronimo%')
    OR (wp_posts.post_excerpt LIKE '%Geronimo%')
    OR (wp_posts.post_content LIKE '%Geronimo%')
  )
)
AND (
  (
    wp_postmeta.meta_key LIKE 'battle_cries'
    AND wp_postmeta.meta_value = 'Geronimo' ) )
    AND wp_posts.post_type IN ('page', 'post')
    AND (wp_posts.post_status = 'publish')
  )
)
</code></pre>
<p>See that AND relation between the two condition groups? That should be an OR. If we extended the <code>pre_get_posts</code> with the hook above WP Query will search for posts which has the keyword in the title, the excerpt or the content and in a meta value by a given key which is obviously a very rare match. So, now we understand the problem, isn't just a setting somewhere? Unfortunately not, you are not allowed to change it. Just look for a function called <code>get_sql_clauses()</code> in <code>wp-includes/class-wp-meta-query.php</code>:</p>
<pre><code class="language-php">&lt;?php
protected function get_sql_clauses() {
    /*
     * $queries are passed by reference to get_sql_for_query() for recursion.
     * To keep $this-&gt;queries unaltered, pass a copy.
     */
    $queries = $this-&gt;queries;
    $sql     = $this-&gt;get_sql_for_query( $queries );

    if ( ! empty( $sql['where'] ) ) {
        $sql['where'] = ' AND ' . $sql['where'];
    }

    return $sql;
}
</code></pre>
<p><a href="https://wordpress.stackexchange.com/questions/229003/filter-by-title-content-and-meta-key-at-the-same-time">Most conversations on Stack Exchange</a> mention things like running two post queries and merge the results into one array. Others recommend creating a unique query variable and replace the role of the <code>s=</code> by <a href="https://jboullion.com/search-post-title-and-meta/">defining your own search conditions</a> in the <code>posts_where</code> hook where you basically write a different search feature for posts.</p>
<h2>My solution</h2>
<p>It's basically a hack, but ignores all the overdrawn above. I would basically override the meta SQL query by using the <code>get_meta_sql</code> hook and replace the first and only the first occurrence of the <strong>AND</strong> relation to an <strong>OR</strong>. I used <code>preg_replace</code>, because the meta SQL query surprisingly has line breaks in it.</p>
<pre><code class="language-php">&lt;?php
function my_theme_modify_meta_sql(
    $sql,
    $queries,
    $type,
    $primary_table,
    $primary_id_column,
    $context
): {
    if ( $context !== null &amp;&amp; $context-&gt;is_search() ) {
        $sql['where'] = preg_replace( '/AND/', 'OR', $sql['where'], 1 );
    }

    return $sql;
}
add_filter( 'get_meta_sql', 'my_theme_modify_meta_sql', 10, 6 );
</code></pre>
<p>It might not the most bulletproof option, however unless core developers won't add a filter for it is the simplest solution which saves you from additional a database queries.</p>
]]></content:encoded>
    </item>
</channel>
</rss>
