<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jason Joseph Nathan</title>
    <description>The latest articles on DEV Community by Jason Joseph Nathan (@jason_nathan).</description>
    <link>https://dev.to/jason_nathan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1662575%2Fb52fb409-5b24-44ab-8626-c410b1635a39.png</url>
      <title>DEV Community: Jason Joseph Nathan</title>
      <link>https://dev.to/jason_nathan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jason_nathan"/>
    <language>en</language>
    <item>
      <title>The 5 Best Downloaders for Videos, Music &amp; Images (No Browser)</title>
      <dc:creator>Jason Joseph Nathan</dc:creator>
      <pubDate>Thu, 11 Sep 2025 19:05:26 +0000</pubDate>
      <link>https://dev.to/jason_nathan/the-5-best-downloaders-for-videos-music-images-no-browser-pm6</link>
      <guid>https://dev.to/jason_nathan/the-5-best-downloaders-for-videos-music-images-no-browser-pm6</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgeekist.co%2Fwp-content%2Fuploads%2FTHE-5-BEST-MEDIA-DOWNLOADERS-scaled.avif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgeekist.co%2Fwp-content%2Fuploads%2FTHE-5-BEST-MEDIA-DOWNLOADERS-scaled.avif" alt="Retro-style Downloads folder with outdated file names alongside a terminal window running a modern media downloader command." width="2560" height="1636"&gt;&lt;/a&gt;Remember downloading at 4KB/sec? These five modern tools are faster and don’t need a browser. Perfect for terminal nerds and nostalgia junkies alike.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://geekist.co/5-best-downloaders-for-music-videos-images-no-browser/" rel="noopener noreferrer"&gt;Source&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tamethetech</category>
      <category>toolsofthetrade</category>
    </item>
    <item>
      <title>You Can Blog from Your Local WordPress Site on iPhone. Here’s How.</title>
      <dc:creator>Jason Joseph Nathan</dc:creator>
      <pubDate>Sun, 18 May 2025 13:58:55 +0000</pubDate>
      <link>https://dev.to/thegeekist/you-can-blog-from-your-local-wordpress-site-on-iphone-heres-how-3m89</link>
      <guid>https://dev.to/thegeekist/you-can-blog-from-your-local-wordpress-site-on-iphone-heres-how-3m89</guid>
      <description>&lt;p&gt;Access your local WordPress site from your iPhone using ZeroTier or Tailscale. Blog from anywhere securely, privately &amp;amp; with no cloud in sight.&lt;br&gt;
&lt;a href="https://geekist.co/you-can-blog-from-your-local-wordpress-site-on-iphone-heres-how/" rel="noopener noreferrer"&gt;Source&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tamethetech</category>
      <category>wheretheuserbegins</category>
    </item>
    <item>
      <title>The Invisible CDN We Built for Display Pics</title>
      <dc:creator>Jason Joseph Nathan</dc:creator>
      <pubDate>Wed, 23 Apr 2025 06:35:14 +0000</pubDate>
      <link>https://dev.to/thegeekist/the-invisible-cdn-we-built-for-display-pics-g6p</link>
      <guid>https://dev.to/thegeekist/the-invisible-cdn-we-built-for-display-pics-g6p</guid>
      <description>&lt;p&gt;We built an invisible CDN using Nginx and PHP with no exposed URLs, zero strain, and avatars that never go stale.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://geekist.co/the-invisible-cdn-we-built-in-2012-for-dynamic-avatars/" rel="noopener noreferrer"&gt;Source&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beneaththestack</category>
      <category>tamethetech</category>
    </item>
    <item>
      <title>The Editorial Engine: A Technologist’s Pilgrimage</title>
      <dc:creator>Jason Joseph Nathan</dc:creator>
      <pubDate>Wed, 16 Apr 2025 05:44:35 +0000</pubDate>
      <link>https://dev.to/thegeekist/the-editorial-engine-a-technologists-pilgrimage-4hee</link>
      <guid>https://dev.to/thegeekist/the-editorial-engine-a-technologists-pilgrimage-4hee</guid>
      <description>&lt;p&gt;What if the reason you’re not writing isn’t discipline, but design? A technologist reflects on blogging and where it all begins.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://geekist.co/the-editorial-engine-a-technologists-pilgrimage/" rel="noopener noreferrer"&gt;Source&lt;/a&gt;&lt;/p&gt;

</description>
      <category>thegeekery</category>
    </item>
    <item>
      <title>Neo Should’ve Picked the Blue Pill</title>
      <dc:creator>Jason Joseph Nathan</dc:creator>
      <pubDate>Wed, 09 Apr 2025 12:28:55 +0000</pubDate>
      <link>https://dev.to/jason_nathan/neo-shouldve-picked-the-blue-pill-31ed</link>
      <guid>https://dev.to/jason_nathan/neo-shouldve-picked-the-blue-pill-31ed</guid>
      <description>&lt;p&gt;A Sci-Fi fable of fat, fire &amp;amp; forgotten biology, where ketosis outshines carb culture &amp;amp; the machines that plugged into the wrong end.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://geekist.co/neo-shouldve-picked-the-blue-pill/" rel="noopener noreferrer"&gt;Source&lt;/a&gt;&lt;/p&gt;

</description>
      <category>fablesforfood</category>
    </item>
    <item>
      <title>We Broke the Web. Can WebO+ Fix It?</title>
      <dc:creator>Jason Joseph Nathan</dc:creator>
      <pubDate>Tue, 18 Mar 2025 06:19:49 +0000</pubDate>
      <link>https://dev.to/jason_nathan/we-broke-the-web-can-webo-fix-it-35cc</link>
      <guid>https://dev.to/jason_nathan/we-broke-the-web-can-webo-fix-it-35cc</guid>
      <description>&lt;p&gt;Let's be honest. The Web has gone through so many self-imposed revolutions, it looks a lot more like a badly managed startup. Pivoting. Perpetually. Forever rewriting its mission statement. But as a side-effect, it tends to generate buzzwords. A ton of them. So here's another one:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;WebO+&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But let’s start at the beginning. We had Web1.0 - which wasn’t a term that was ever actually coined - but was known as the &lt;em&gt;read-only web&lt;/em&gt;. Then Web2.0 came with all its interactivity and API-driven web apps. And finally, we met Web3. What’s next?&lt;/p&gt;

&lt;p&gt;I’d say that after 25 years of (re)inventing complexity, we don’t need Web4. We just need to fix Web2.0. But before we talk about the fix, let’s talk about how we broke it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Full article below. Originally posted on &lt;a href="https://geekist.co/we-broke-the-web-can-webo-fix-it" rel="noopener noreferrer"&gt;geekist.co&lt;/a&gt;. Do subscribe for updates!&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Web. What Went Wrong?
&lt;/h2&gt;

&lt;p&gt;It began as a beautifully simple thing. Somewhere out there, there was a computer that held a ton of webpages. And then, there were tons of computers - with tons of webpages - ready to serve any one who requested them.&lt;/p&gt;

&lt;p&gt;You would pick your favorite browser application (probably Netscape) and fire it up. And then you’d be greeted with AltaVista (depending on the year, it might even be Yahoo) and then you’d type in a search and Boom!&lt;/p&gt;

&lt;p&gt;But it wasn’t just a tool. It was a cultural moment. This old Yahoo! ad captures the vibe perfectly.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/RguxFYvBFiE"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;em&gt;This was one of my absolute favourites ads at the time!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But something wasn’t right. The web was… boring. Sure, you could read stuff. But why couldn’t we have the same interactivity we had in games? Why couldn’t the Web feel alive?&lt;/p&gt;

&lt;p&gt;And why not? That’s when Web2.0 was born.&lt;/p&gt;

&lt;h2&gt;
  
  
  Web2.0: The Social &amp;amp; API-Driven Web (Mid-2000s – 2020s)
&lt;/h2&gt;

&lt;p&gt;Suddenly, web pages transformed from regular Wikipedia looking articles to full blown Web Applications.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The term &lt;strong&gt;Web Application&lt;/strong&gt; actually felt triumphant. No serious programmer at the time thought much about Web Developers. No one would dare call us &lt;strong&gt;Engineers&lt;/strong&gt;. Very few even wanted to call us &lt;strong&gt;Programmers.&lt;/strong&gt; You could almost hear them mutter under their breath:&lt;/p&gt;

&lt;p&gt;“What? JavaScript? PHP? Ewww…”&lt;/p&gt;

&lt;p&gt;Many thought we were “Java” fan boys and girls. Meanwhile, some of us made their salaries look cute.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then came the &lt;strong&gt;Buzzword Bonanza™&lt;/strong&gt; - AJAX, JSONP, OAuth. Suddenly, the &lt;strong&gt;FrontEnd Engineer&lt;/strong&gt; (oops, &lt;em&gt;developer&lt;/em&gt;) was born. And just like that, frameworks exploded. Your Yahoo! wasn’t Yahoo anymore - literally.&lt;/p&gt;

&lt;p&gt;You could suddenly do more. You could talk! Err… chat! And guess what else?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You could totally click on a Button and you wouldn’t have to wait a week for the page to reload!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And it didn’t stop there. Buttons changed color, shapes moved, hover effects responded before you even clicked. The web came alive. Stuff glowed. Things got bolder. Move your mouse, and… something popped out!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Oh, and in case you were wondering, yes, that’s totally where popups came from. At least until we invented pop-up blockers to fight back.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It was a game changer: Skeuomorphic design, Zoomable User Interfaces (&lt;a href="https://geekist.co/building-a-zoomable-user-interface-with-meteorjs-greensock" rel="noopener noreferrer"&gt;remember this?&lt;/a&gt;) and of course, the rise of Social Media.&lt;/p&gt;

&lt;p&gt;The web became &lt;strong&gt;Live&lt;/strong&gt;. &lt;strong&gt;Fun&lt;/strong&gt;. &lt;strong&gt;&lt;em&gt;Interactive&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But beyond the flashy buttons, glowing elements and real-time interactions, something bigger was happening…&lt;/p&gt;

&lt;p&gt;Browsers weren’t just rendering cool effects; they were offloading serious computation from our servers to our users’ machines. Instead of relying on expensive, multi-core, memory-filled servers, we realized that every single user already had compute power at their fingertips.&lt;/p&gt;

&lt;p&gt;We went from the browser rendering pages to the browser rendering entire applications, &lt;strong&gt;full-blown, desktop-grade software.&lt;/strong&gt; The browser became the new runtime; an OS inside an OS, shouldering the burden once meant for the backend.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;At this point, people were finally calling us Engineers. Well… no. We were calling ourselves Engineers. And loudly. And no one was arguing with us.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It was a brilliant move.&lt;/p&gt;

&lt;p&gt;Until it wasn’t.&lt;/p&gt;

&lt;h3&gt;
  
  
  SEO took a NoseDive
&lt;/h3&gt;

&lt;p&gt;Turns out, search engines didn’t sign up for this full-stack revolution. Google could read JavaScript, sure. But understand it? Not so much. Beyond that, performance tanked. I’m sure you’re saying, &lt;em&gt;“But wait. No it didn’t!”&lt;/em&gt;. It did, but you probably didn’t feel it because we were graciously met with so much more compute power, much more than we ever did before&lt;/p&gt;

&lt;p&gt;Developers were shipping megabytes of JavaScript just to render something as simple as a list. What once took a single HTML file now required hydration, client-side loops, and API calls. It suddenly took tons of JS to make anything functional. In turn, that created new problems. Latency suffered. We had to figure out how to pre-render out static pages (remember PhantomJS anybody?).&lt;/p&gt;

&lt;p&gt;Then came React.&lt;/p&gt;

&lt;p&gt;Then came the first hydration issues.&lt;/p&gt;

&lt;p&gt;Then came Hydra. Cut off one head, two shall take its place… Sorry. Hydration Hell.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkmcpg71drktd2w8fh7g5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkmcpg71drktd2w8fh7g5.gif" alt="Hydra: Cut off one head, two shall take its place" width="640" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if that wasn’t enough, something even worse was happening behind the scenes. While we were drowning in hydration hell, large organisations were quietly harvesting our data - and selling it. How? They made shiny cool things we could use for free and made us accept terms no one bothered to read.&lt;/p&gt;

&lt;p&gt;The cracks weren’t just showing, they were splitting wide open. The web had become a bloated, exploitative mess, and no one knew where to start fixing it.. We needed something new…&lt;/p&gt;

&lt;h2&gt;
  
  
  Web3. The Decentralized, Crypto-Powered Web (2020s – Now)
&lt;/h2&gt;

&lt;p&gt;Notice something? We got cooler. We dropped the &lt;code&gt;.0&lt;/code&gt;. Just Web3. Clean. Minimalist. Sleek.&lt;/p&gt;

&lt;p&gt;Oh dear God, no. Not even close.&lt;/p&gt;

&lt;p&gt;At least we got new buzzwords! &lt;em&gt;Blockchain. Crypto. Smart Contracts. Decentralization. Tokens. Mining. NFTs.&lt;/em&gt; You get the idea. Web3 came in hot, promising to fix the internet by removing central control and letting users own their data. And in many ways, it delivered - for finance, supply chains, trustless transactions and so much more.&lt;/p&gt;

&lt;p&gt;But that didn’t actually fix any of our Web2.0 architectural problems, no sir. In fact, people started slapping blockchain on everything. Suddenly, blogs needed tokens, APIs required smart contracts and even basic web apps were being rebuilt with decentralized infrastructure. So instead, it just added more to account for.&lt;/p&gt;

&lt;p&gt;At this point, we had truly outdone ourselves. In pushing the boundaries of technology, we didn’t just innovate,&lt;em&gt;we over-engineered everything.&lt;/em&gt; And in the process, we gave an old word a brand-new meaning:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Overkill.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But. Finally. After years of over-complication, we hit The Great Reset.&lt;/p&gt;

&lt;h2&gt;
  
  
  WebO+. The ultimate Rollback-olution™ (2020s – Now)
&lt;/h2&gt;

&lt;p&gt;It’s absurd how we’ve come full circle. We began with server-side rendering because that’s all we had. Then JavaScript evolved, and we pushed more work onto the client. Then came Internet Explorer, which we shall not speak of. Eventually, we decided that sending full HTML pages was too expensive - so we switched to sending JSON. Then, JSON was too big, so we optimized it with better compression. Then, in our pursuit of the ‘pristine’ server, we decided it should only speak one language - JSON (or protobuf) - while the client handled the heavy lifting.&lt;/p&gt;

&lt;p&gt;Then reality struck. We still needed server-side rendering for SEO, accessibility and performance. But instead of admitting the mistake, we Frankenstein’d a solution - client-based SSR. And after years of jumping through hoops, we arrived back where we started: &lt;strong&gt;Server-side Rendering.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The simple truth hit us: The &lt;strong&gt;original web had it right all along&lt;/strong&gt;. We didn’t need a new paradigm. We needed to stop over-engineering everything.&lt;/p&gt;

&lt;p&gt;WebO+ isn’t about going backwards - it’s about correcting 25 years of misdirection. It takes the best parts of Web1, Web2, and Web3 and cuts out the nonsense.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Web1&lt;/th&gt;
&lt;th&gt;Web2&lt;/th&gt;
&lt;th&gt;Web3&lt;/th&gt;
&lt;th&gt;WebO+&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Server-side HTML&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UI Rendering APIs&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SEO-Friendly&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Perf (Page Load)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Heavy&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Client JS&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (dApps)&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;WebO+ is what Web1 would have been, if we had today’s hardware, compression, and smarter rendering.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What it does right.
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Now this is assuming you still need a server to make API calls and you’re not generating static pages and serving them out of CDN.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For starters, we’re back to the early 2000s where server-rendered, SEO-friendly pagination still matters, even though client-side tricks like pull-to-refresh make browsing smoother.&lt;/p&gt;

&lt;p&gt;But now, servers are more powerful, and compression is faster than ever. Instead of juggling JSON responses and complex client-side loops, the server just sends fully rendered HTML, and the browser drops it straight into the DOM. No extra processing, no unnecessary hydration, just fast, direct rendering.&lt;/p&gt;

&lt;p&gt;Yes, you can still use JS/TS on the backend, and yes, you can still reuse the same logic for both server-side and client-side rendering. But some tasks like click handlers and state changes must stay client-side.&lt;/p&gt;

&lt;p&gt;The difference? You don’t need to structure two separate component types anymore. Just sprinkle in client-side functionality where needed.&lt;/p&gt;

&lt;p&gt;Some frameworks, like Svelte, go further by allowing client-side logic within the same file, making the distinction seamless.&lt;/p&gt;

&lt;p&gt;And it’s not just Svelte. SSR is back across the board. Frameworks like Laravel, Next, Nuxt and SvelteKit have brought server rendering back into the mainstream, making it practical again: lean servers, fully rendered pages, instant loads.&lt;/p&gt;

&lt;p&gt;React now embraces SSR with Next.js and React Server Components (RSC), though hydration issues still make it more complex than traditional SSR.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Small Aside, What Inspired this Article?
&lt;/h3&gt;

&lt;p&gt;You see, I saw a video called &lt;em&gt;“Next.js Best Practices You can’t ignore”&lt;/em&gt; and the first thing the author said was something along the lines of “Dude, are you using Page Router? Stop. Use App Router.” but he didn’t do much of a job elaborating. So curiously, I asked ChatGPT about it and this is the gist of what I got back:  &lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Oh, App Router is like how we built websites in the late 90s and early 2000s.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And then. Something inside me broke.&lt;/p&gt;

&lt;p&gt;So I forced my partner to sit down and listen to me rant. I went on and on and finally ended with telling her what I would say to Devs at the time:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;It doesn’t matter if the server-side code is pristine gold if your client-side code looks like Medusa just woke up from a freggin’ hangover.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;She laughs. That’s something I guess. And the ranting made me feel better so before I go, there are some more things that need to be said.&lt;/p&gt;

&lt;p&gt;Frontend Development pushed browsers so damn far that they became full-fledged operating systems. _Chromebook anyone?_&lt;/p&gt;

&lt;p&gt;It pushed GPUs to their limits. It pushed JS engines to the point where V8 became so powerful that it didn’t just optimize web performance - it gave birth to entire server-side ecosystems like Node.js &amp;amp; Deno. (Yep. The same dude started both)&lt;/p&gt;

&lt;p&gt;Meanwhile, server-side computing kept getting stronger. But most of these BFFs were just sitting there, idling. So the push came from the frontend: “Wake up, server. We need you to do more.”&lt;/p&gt;

&lt;p&gt;We’re finally waking up to the fact that frontend wasn’t supposed to be doing all the heavy lifting.&lt;/p&gt;

&lt;p&gt;Finally. We are shifting back. So I’d say…&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Goodbye hydration hell.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Goodbye unnecessary client-side API calls.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Goodbye shipping 5MB of JavaScript just to render a list.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And then I'll say…&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Welcome back, server-rendered HTML.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Welcome back, pre-rendered content.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Welcome back universal UIs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔥 Welcome to WebO+.
&lt;/h3&gt;

</description>
      <category>webo</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>backend</category>
    </item>
    <item>
      <title>I can't believe it took me 5 years to stumble upon such a good read. :)</title>
      <dc:creator>Jason Joseph Nathan</dc:creator>
      <pubDate>Mon, 17 Mar 2025 05:09:47 +0000</pubDate>
      <link>https://dev.to/jason_nathan/i-cant-believe-it-took-me-5-years-to-stumble-upon-such-a-good-read--1og</link>
      <guid>https://dev.to/jason_nathan/i-cant-believe-it-took-me-5-years-to-stumble-upon-such-a-good-read--1og</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/_staticvoid" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F24722%2F502c728f-8a3a-4e5d-a038-e137d9fbe8bc.jpg" alt="_staticvoid"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/_staticvoid/node-js-under-the-hood-7-the-new-v8-4gd6" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Node.js Under The Hood #7 - The new V8&lt;/h2&gt;
      &lt;h3&gt;Lucas Santos ・ Jan 5 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#node&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#v8&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>node</category>
      <category>javascript</category>
      <category>v8</category>
    </item>
    <item>
      <title>Why Your Tech Stack is Overrated (And What Actually Matters)</title>
      <dc:creator>Jason Joseph Nathan</dc:creator>
      <pubDate>Thu, 13 Mar 2025 17:53:10 +0000</pubDate>
      <link>https://dev.to/jason_nathan/why-your-tech-stack-is-overrated-and-what-actually-matters-4g56</link>
      <guid>https://dev.to/jason_nathan/why-your-tech-stack-is-overrated-and-what-actually-matters-4g56</guid>
      <description>&lt;h3&gt;
  
  
  The Debate That Didn’t Matter
&lt;/h3&gt;

&lt;p&gt;In 2017, everyone - including yours truly - was passionately caught up debating the virtues of &lt;a href="https://www.inovex.de/de/blog/react-native-vs-native-development/" rel="noopener noreferrer"&gt;React Native versus going fully Native&lt;/a&gt;. I even penned a fiery rant about it &lt;a href="https://geekist.co/hybrid-vs-native" rel="noopener noreferrer"&gt;here&lt;/a&gt;, convinced I'd cracked the code myself on app development.&lt;/p&gt;

&lt;p&gt;But looking back now, it feels like we were totally arguing about who had the cooler shoes in primary school which as fun as it was at the time, was ultimately meaningless. The truth is, it wasn't frameworks or flashy tech that determined success; it was something &lt;em&gt;far more mundane&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Real success hinged on fundamentals like &lt;a href="https://www.archdaily.com/904882/understanding-and-using-architectural-scales" rel="noopener noreferrer"&gt;choosing an architecture&lt;/a&gt; that &lt;a href="https://aosabook.org/en/v2/distsys.html" rel="noopener noreferrer"&gt;scales&lt;/a&gt;, keeping logic decoupled and resisting those tempting short-term optimisations that always seem clever until you're buried under technical debt months later.&lt;/p&gt;

&lt;p&gt;Turns out, frameworks come and go, but good architecture? That sticks around.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Actually Matters for Future-Proof Software&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If I could distill the years between 2017 and today into a single insight, it’d be this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Frameworks fade; the way you structure your software endures.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;AI and Automation Changed Everything&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;At the time, having &lt;a href="https://naturaily.com/blog/react-native-things-to-know" rel="noopener noreferrer"&gt;JavaScript run everywhere was groundbreaking&lt;/a&gt;. Today, AI and automation have transformed the landscape completely. Debugging, for example, used to mean long nights hunting obscure errors. Now, AI-assisted tools help pinpoint common issues in minutes, making troubleshooting more efficient - but its far from perfect.&lt;/p&gt;

&lt;p&gt;Automated CI/CD pipelines have made updates effortless across every platform, no longer making deployment feel like a stressful space launch. Even components and tests can now be generated with AI, freeing developers from tedious, repetitive tasks to focus on higher-level design.&lt;/p&gt;

&lt;p&gt;The future doesn’t care if your stack is cool; it cares how quickly and reliably you can adapt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security Finally Gets Its Due&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Security was still a hot topic then too but not many knew what exactly to do beyond the understood norms and it often felt like an afterthought - we built fast and hoped nothing was vulnerable. Today, security isn't optional; it's essential from day one.&lt;/p&gt;

&lt;p&gt;Modern threats, like AI-powered cyberattacks and vulnerabilities hidden deep in supply chains, weren't even on our radar back then. &lt;a href="https://developers.google.com/solutions/content-driven/data-storage/regulatory-compliance" rel="noopener noreferrer"&gt;Regulatory compliance&lt;/a&gt; now also demands that security be baked into the foundation of every application. Building resilient software isn't about paranoia, (well it is slightly) it's about responsibility and longevity.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI in Coding went from Novelty to Necessity (Almost)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://siliconangle.com/2017/08/15/a-cloud-guru-uses-lambda-and-api-gateway-to-build-serverless-company-awssummit/" rel="noopener noreferrer"&gt;AWS Lambda&lt;/a&gt; and serverless computing? Pure Revolution. Today we have coding platforms that generate entire apps for you (It can, but the stuff it generates is quite rudimentary). I have never once thought (nor will I believe) that coding can be completely replaced by AI - yet!&lt;/p&gt;

&lt;p&gt;The reason I say this is because I have spent much more time debugging AI-generated code than I would my own. To start with, I wouldn’t have written many things the way it would, having learnt so much over the years, I structure things wildly different from the common scenarios that LLMs are trained with. But while AI-generated code still has a long way to go, its real value emerges elsewhere…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2naou0oqk0d72gii8m0x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2naou0oqk0d72gii8m0x.png" alt="AI-Assisted Coding Workflow: How AI and Human Oversight Work Together" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today, we have low-code and no-code tools that can generate prototypes in hours instead of weeks. And it is things like this that make AI shine. The heavy lifting, the project starters, the strategic overview. After that it becomes a companion at best. This converts developers into strategic architects, crafting scalable systems rather than wrestling with mundane details. If anything, these tools elevated our roles by freeing us from the busy work.&lt;/p&gt;

&lt;p&gt;Personally, I prefer using AI to handle specific parts of the code where structure or organisation can be enhanced, rather than relying on it entirely&lt;/p&gt;

&lt;p&gt;I’d say LLM generated code has a long way to go and even if it gets there, you’d still need humans in the mix - and by definition - these humans are likely coders themselves because who else is going to debug AI’s mistakes?&lt;/p&gt;

&lt;p&gt;I am hopeful though, and I am really looking forward to it because that means I can focus on things that really matter and leave the grunt-work to something else.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I’ll write about some of the tools I have reviewed in an upcoming article, giving you a better understanding on what’s out there now and how it can complement your workflow.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Microservices vs. Monoliths: Déjà Vu All Over Again
&lt;/h3&gt;

&lt;p&gt;Just as 2017 had its React Native drama, today's hot debate is "microservices or monolith?" It's tempting to pick a side and argue until you're blue in the face but here's what history has taught us:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Neither one is a silver bullet.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sure, a monolith might get your MVP out the door faster, but as complexity grows, it starts to feel like lugging around an increasingly heavy backpack. Microservices offer flexibility and modularity, but demand strict discipline to keep complexity in check.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The trick is to build a monolith with the future in mind. Code structured around isolated business units or features stands the test of time.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;(Crap! That rhymed!)&lt;/p&gt;

&lt;p&gt;Practically speaking, your code should communicate through clearly defined interfaces - a common protocol if you will. This could be REST, GraphQL, or an event-driven architecture, depending heavily on your infrastructure, team expertise and available resources&lt;/p&gt;

&lt;p&gt;If each feature-driven section of your codebase can live and operate independently within your stack, transitioning from a monolithic structure to a standalone microservice becomes a surprisingly smooth process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Real Lesson is that The Framework Was Never the Point&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I wasted way too many hours back then debating the merits of frameworks, only to realise years later how pointless it was. Winning arguments didn't make software any better; understanding longevity did.&lt;/p&gt;

&lt;p&gt;Since then, I've been fortunate to lead numerous mobile development projects. One highlight was at Prudential, where we built federated React Native components used across various markets. The framework itself? Just a means, never the end.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Final Thought, a Look Beyond Today's Trends
&lt;/h3&gt;

&lt;p&gt;When picking your tech stack today, don't ask yourself, "Will this still be cool in 2025?" Instead, challenge yourself with, "Will this still be relevant in 2030?" If your answer depends heavily on a particular framework, you might already be falling behind.&lt;/p&gt;

&lt;p&gt;Remember, tech stacks are transient, but good architecture and thoughtful design decisions are timeless.&lt;/p&gt;

</description>
      <category>aiincoding</category>
      <category>architecture</category>
      <category>programming</category>
      <category>automation</category>
    </item>
    <item>
      <title>WordPress MVC Plugin Reboot 2024</title>
      <dc:creator>Jason Joseph Nathan</dc:creator>
      <pubDate>Wed, 25 Dec 2024 04:00:00 +0000</pubDate>
      <link>https://dev.to/thegeekist/wordpress-mvc-plugin-reboot-2024-32ne</link>
      <guid>https://dev.to/thegeekist/wordpress-mvc-plugin-reboot-2024-32ne</guid>
      <description>&lt;h2&gt;
  
  
  Thoughts on the simplicity of an older solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Revisiting the WordPress MVC Router: A 2024 Update
&lt;/h3&gt;

&lt;p&gt;So I stumbled upon an old database dump of Wordpress backups over the years and chanced a 2010 article I wrote that I thought was interesting. So I extracted, and decided to test everything out before I posted it on Geekist.&lt;/p&gt;

&lt;p&gt;I’ve got to say, it really did surprise me. Logic from some 15 years ago still worked! So I decided I’d push the &lt;a href="https://github.com/theGeekist/2010-router-plugin-example" rel="noopener noreferrer"&gt;code to a repo&lt;/a&gt;, add some screenshots and give &lt;a href="https://geekist.co/wordpress-mvc-plugin-development" rel="noopener noreferrer"&gt;the article&lt;/a&gt; some well deserved love.&lt;/p&gt;

&lt;p&gt;Fast forward to today, so much has changed with plugin development in WordPress, It has matured with frameworks and best practices, yet I’d still say that the core idea of a lightweight, custom router remains quietly powerful.&lt;/p&gt;

&lt;p&gt;But let's revisit this in the context of what’s available now.&lt;/p&gt;

&lt;h3&gt;
  
  
  The WordPress Plugin Framework Landscape
&lt;/h3&gt;

&lt;p&gt;Here are a few notable frameworks and tools for WP plugin development&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://wppb.me" rel="noopener noreferrer"&gt;WP Plugin Boilerplate&lt;/a&gt;:
A standardized, object-oriented foundation for WordPress plugin development. It’s built on best practices and helps developers maintain clean, modular code.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.wordpress.org/cli/commands/scaffold" rel="noopener noreferrer"&gt;WP Scaffold&lt;/a&gt;:
A command-line tool that generates boilerplate code for plugins and themes. It doesn’t enforce MVC but provides a solid starting point for structured development.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://timber.github.io/docs/v2/" rel="noopener noreferrer"&gt;Timber&lt;/a&gt;:
It seems primarily focused on themes (templates), but Timber uses the MVC pattern and integrates with plugins to help structure admin interfaces.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pods.io/" rel="noopener noreferrer"&gt;Pods Framework&lt;/a&gt;:
From what I gather, it does magic with custom content types and has powerful tools for building admin interfaces, with hooks and filters that align well with MVC-inspired routing.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Why Revisit the Simple Router?
&lt;/h3&gt;

&lt;p&gt;Because with more features, comes complexity and a steeper learning curve. Sometimes, all you need is a lightweight, no-frills solution.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Also… there’s absolutely nothing close to creating the building blocks of your own reusable framework - especially for smaller or personal plugins.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The beauty of the router I introduced in 2010 (and the updated one below) lies in its simplicity. It maps URLs to controllers &amp;amp; methods and that gives you a great starting point to quickly structure plugins, avoid repetitive code and to scale functionality without introducing heavy dependencies.&lt;/p&gt;

&lt;p&gt;And no, it’s not gonna replace WP Plugin Boilerplate for sure, but hey, there is really nothing stopping you from using both.&lt;/p&gt;

&lt;h3&gt;
  
  
  Updated Simple Router for 2024
&lt;/h3&gt;

&lt;p&gt;Let’s dive into the updated router for 2024, which now includes a middleware implementation, auth checks, input validation and exception handling.&lt;/p&gt;

&lt;h4&gt;
  
  
  The New Router Class
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Router
{
  protected $middleware = [];
  protected $middleware_instances = [];
 // ...other methods below
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So if we have a psuedo-MVC framework, it really does make sense to include some sort of middleware implementation. Here &lt;code&gt;$middleware&lt;/code&gt; is a property holding defined middleware for the class and &lt;code&gt;$middleware_instances&lt;/code&gt; hold instantiated instances. More on this later.&lt;/p&gt;

&lt;h4&gt;
  
  
  Constructor and Initial Setup
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function __construct(
  $route,
  $default_controller,
  $default_method,
  $middleware = []
) {
  $this-&amp;gt;middleware = $middleware;
  $this-&amp;gt;perform_auth_checks();
  $try = $this-&amp;gt;route_it($route, $default_method);
  if ($try === false) {
    $this-&amp;gt;default_route_it(
      $default_controller,
      $default_method,
      $route[2]
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;$route&lt;/code&gt;, in this case is an array consisting of the extracted &lt;code&gt;$_GET&lt;/code&gt; variables, namely &lt;code&gt;‘page‘&lt;/code&gt; and &lt;code&gt;‘action‘&lt;/code&gt;. This is provided by &lt;code&gt;plugin.php&lt;/code&gt; when this class is instantiated. We try the provided route, if not we fall back to the default route. We also have an optional array &lt;code&gt;$middleware&lt;/code&gt; saved.&lt;/p&gt;

&lt;h4&gt;
  
  
  Route Handling
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;route_it&lt;/code&gt; method determines which controller and method to execute based on the request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function route_it(
  $controller,
  $method,
  $parameters = [],
  $default_method
) {
  try {
    $obj = class_exists($controller)
      ? new $controller()
      : false;
    if (!$obj) {
      return false;
    }
    $method_exists = method_exists($obj, $method);
    $default_method_exists = !$method_exists
      &amp;amp;&amp;amp; method_exists($obj, $default_method);
    if (!$method_exists &amp;amp;&amp;amp; !$default_method_exists) {
      return false;
    }
    $this-&amp;gt;execute_middleware(
      $controller,
      $method_exists ? $method : $default_method,
      $parameters
    );
    return $method_exists
      ? $obj-&amp;gt;$method($parameters)
      : $obj-&amp;gt;$default_method($parameters);
  } catch (Exception $e) {
    $this-&amp;gt;handle_exception($e);
  }
  return false;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We first check if a controller exists:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class_exists($controller);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then we check to see if the called action exists&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;method_exists($obj, $method);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or that at least that the default action (usually named &lt;code&gt;index&lt;/code&gt;) exists&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;method_exists($obj, $default_method);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If none of the above checks out, we return false, otherwise we execute the defined middleware before passing control to the controller.&lt;/p&gt;

&lt;h4&gt;
  
  
  Middleware Execution
&lt;/h4&gt;

&lt;p&gt;Middleware execution is optimized to reuse existing instances.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;protected function execute_middleware(
  $controller,
  $method,
  $parameters
) {
  foreach ($this-&amp;gt;middleware as $key =&amp;gt; $mw) {
    if (!isset($this-&amp;gt;middleware_instances[$key])) {
      if (class_exists($mw)) {
        $this-&amp;gt;middleware_instances[$key] = new $mw();
      } else {
        throw new Exception("Middleware class $mw not found.");
      }
    }
    $middleware_instance = $this-&amp;gt;middleware_instances[$key];
    if (method_exists($middleware_instance, 'handle')) {
      $middleware_instance-&amp;gt;handle(
        $controller,
        $method,
        $parameters
      );
    } else {
      throw new Exception(
        "Middleware class $mw does not have a handle method."
      );
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a simple way to ensure that we don't instantiate all the middleware for each request and is included here to illustrate how this can be done. However, another great way to include this is within your plugin's startup code itself. That way, your plugin's first page load wouldn't take too long if you have tons of middleware!&lt;/p&gt;

&lt;h4&gt;
  
  
  Fallback Route Handling
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;default_route_it&lt;/code&gt; method handles fallback routes when the specified route fails.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function default_route_it(
  $controller,
  $method = "index",
  $parameters = []
) {
  try {
    $obj = class_exists($controller)
      ? new $controller()
      : false;
    if (!$obj) {
      throw new Exception("Controller not found: $controller");
    }
    $method_exists = method_exists($obj, $method);
   if(!$method_exists) {
    throw new Exception("There is no default '$method' method found in $controller");
  }
    $this-&amp;gt;execute_middleware(
      $controller,
      $method,
      $parameters
    );
  $obj-&amp;gt;$method($parameters);
  } catch (Exception $e) {
    $this-&amp;gt;handle_exception($e);
  }
  return false;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method is pretty much the same as the 2010 version. The only difference is the added middleware execution. This method helps when your controllers have a default action (&lt;code&gt;index&lt;/code&gt; in this case) and will be used as to display first page of the menu item that a controller handles&lt;/p&gt;

&lt;h4&gt;
  
  
  Authentication Checks
&lt;/h4&gt;

&lt;p&gt;Basic authentication logic is enforced during construction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;protected function perform_auth_checks() {
  if (!isset($_SESSION['user'])) {
    throw new Exception("Unauthenticated access detected.");
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This saves you the hassle of checking for an authenticated user within each controller and it serves as an example of how you can include mandatory checks for your plugin.&lt;/p&gt;

&lt;h4&gt;
  
  
  Exception Handling
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;handle_exception&lt;/code&gt; method provides a standard mechanism for logging and displaying errors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function handle_exception(
  $e
) {
  error_log($e-&amp;gt;getMessage());
  wp_die(
    "An error occurred: " . $e-&amp;gt;getMessage()
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example above is rudimentary but you can expand on it to write to a log file, store a database entry (or even &lt;code&gt;Sentry&lt;/code&gt;) when your plugin encounters exception.&lt;/p&gt;

&lt;h4&gt;
  
  
  How Do We Use This Exactly?
&lt;/h4&gt;

&lt;p&gt;I'll have to admit, the original post - back in 2010 - was a little abstract so I hope the screenshot above helps to clear things up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0aujm9bgpha3m6t7qg98.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0aujm9bgpha3m6t7qg98.png" alt="Contacts dashboard view rendered by the index action of the Contacts controller." width="588" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each menu item on the left is a controller class you define. If you look at the URL, you'd see that &lt;code&gt;$_GET&lt;/code&gt; variables list &lt;code&gt;page=CRM&lt;/code&gt; with no action defined. So the page you see in the screenshot points to the &lt;code&gt;Contacts&lt;/code&gt; controller class and the default &lt;code&gt;index&lt;/code&gt; action. I am hoping to include a link to a GH repo with example code of this functionality some time soon, so do subscribe to the newsletter for updates. In the meantime, working code for the original router is still &lt;a href="https://github.com/theGeekist/2010-router-plugin-example" rel="noopener noreferrer"&gt;available here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;I hope this article inspires you with at least one way of organizing your plugin code. If you have questions or thoughts, do share them in the comments!&lt;/p&gt;




</description>
      <category>tamethetech</category>
      <category>toolsofthetrade</category>
    </item>
    <item>
      <title>Nginx Wildcard SSL and Beyond</title>
      <dc:creator>Jason Joseph Nathan</dc:creator>
      <pubDate>Fri, 20 Dec 2024 03:08:16 +0000</pubDate>
      <link>https://dev.to/jason_nathan/nginx-wildcard-ssl-and-beyond-4ld9</link>
      <guid>https://dev.to/jason_nathan/nginx-wildcard-ssl-and-beyond-4ld9</guid>
      <description>&lt;p&gt;A breakdown of SSL/TLS, Let’s Encrypt, and Mutual SSL with Nginx, covering wildcard certs, Cloudflare integration, and advanced security configurations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://geekist.co/wildcard-ssl-and-beyond/" rel="noopener noreferrer"&gt;Source&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beneaththestack</category>
      <category>tamethetech</category>
    </item>
    <item>
      <title>It's a Security Thing.</title>
      <dc:creator>Jason Joseph Nathan</dc:creator>
      <pubDate>Sun, 15 Dec 2024 09:10:10 +0000</pubDate>
      <link>https://dev.to/jason_nathan/its-a-security-thing-2h3e</link>
      <guid>https://dev.to/jason_nathan/its-a-security-thing-2h3e</guid>
      <description>&lt;p&gt;My old Heardable Inc boss was formerly in TV production. Heardable, as you might have heard of, was a brand analytics company way ahead of its time.&lt;/p&gt;

&lt;p&gt;We were setting up a high-stakes professional &lt;a href="https://www.youtube.com/watch?v=BqUhLWgfGXI" rel="noopener noreferrer"&gt;YouTube interview with the Global CEO (David Sable)&lt;/a&gt; of Y&amp;amp;R (one of our incubators at the time), and we wanted to use this event to showcase our brand-new Heardable product - where I was CTO.&lt;/p&gt;

&lt;p&gt;Everything was set up, and we were awaiting the arrival of David and other important folks.&lt;/p&gt;

&lt;p&gt;I knew the app had a bug that required the Meteor Mongo DB to be reset to clear the cache before the demo.&lt;/p&gt;

&lt;p&gt;You see, the thing about Meteor &amp;amp; Mongo is that in the early days of 2015, there was no way of telling their REPLs apart, Meteor's shell looked almost exactly the same as Mongo's shell.&lt;/p&gt;

&lt;p&gt;So instead of typing this in the &lt;em&gt;Meteor Shell&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; mongo reset
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I typed this in the &lt;em&gt;Mongo Shell&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; mongo reset
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which. Well... It kinda... Uhm... Reset the entire DB.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Seriously though, which part of the above looked bloody different to you??&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Right! I thought. Ten minutes to his arrival, and I just cleared out the DB.&lt;/p&gt;

&lt;p&gt;Golden.&lt;/p&gt;

&lt;p&gt;Okay, no problem, you got this. There's a backup you did a couple days ago. Grab it and restore it and everything's gonna be right as day.&lt;/p&gt;

&lt;p&gt;But there was one problem.&lt;/p&gt;

&lt;p&gt;My boss, whose account was going to be used for the demo, had changed her password after the backup, meaning she would have to "Reset Password" before the demo because the backup contained her older one.&lt;/p&gt;

&lt;p&gt;Damn, I thought. Why in the world would someone change a password for a non-production server?&lt;/p&gt;

&lt;p&gt;Two minutes to his arrival, and my boss walks in.&lt;/p&gt;

&lt;p&gt;"All good?" she asked.&lt;/p&gt;

&lt;p&gt;"Yes!" I said, "Just that I need you to do something real quick Can you reset your password?"&lt;/p&gt;

&lt;p&gt;"Now?!" she asked. "You kidding?", she continues, in absolute disbelief and exasperation.&lt;/p&gt;

&lt;p&gt;Calmly, I said, "Francine? Yes. Now."&lt;/p&gt;

&lt;p&gt;She reset the password, and Ron Hart (the CTO of DropSuite) walked in just as the drama was ending.&lt;/p&gt;

&lt;p&gt;"What's going on?" he asked. "Nothing," I said. "All good."&lt;/p&gt;

&lt;p&gt;But Francine (my boss) couldn't resist chiming in, "He just made me reset my password!"&lt;/p&gt;

&lt;p&gt;"Just a &lt;em&gt;security thing&lt;/em&gt;" I said, lying through my teeth. Ron didn't say a word, but the look on his face said it all:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Yeah, sure it is&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Meanwhile, David Sable arrives, and Francine leaves my office. I couldn't take the pressure and went out the back door for a smoke.&lt;/p&gt;

&lt;p&gt;Ron came out to join me. He lit himself a cigarette, looked out into the car park in the same direction I was facing - and without turning his head - took a puff and asked,&lt;/p&gt;

&lt;p&gt;"You f**ked up, didn't ya?"&lt;/p&gt;

&lt;p&gt;I took a puff and said, "Yep."&lt;/p&gt;

&lt;p&gt;He continues, in the same posture, "How bad?"&lt;/p&gt;

&lt;p&gt;I said, "Well. How'd you rate resetting the DB?"&lt;/p&gt;

&lt;p&gt;He replies, "Yep. Bad."&lt;/p&gt;

&lt;p&gt;Were still not facing each other, casually looking out into the distance.&lt;/p&gt;

&lt;p&gt;He takes another puff, then continues: "You fixed it?"&lt;/p&gt;

&lt;p&gt;I replied, after another puff, "Yeah, restored a backup from a couple days ago."&lt;/p&gt;

&lt;p&gt;He pauses for a bit, thinking about it, then asks absurdly,&lt;/p&gt;

&lt;p&gt;"So you mean between the backup and today, she changed her password?"&lt;/p&gt;

&lt;p&gt;I replied, "Yeapp."&lt;/p&gt;

&lt;p&gt;He then shrugs, puts out his cigarette, and declares, "Yep totally a &lt;em&gt;security thing&lt;/em&gt; Let's get back inside."&lt;/p&gt;

&lt;p&gt;"Yep," I said, putting out my cigarette.&lt;/p&gt;

&lt;p&gt;And as if it was nothing more than a smoke break, we walked inside to greet the VIPs and show off the new product demo.&lt;/p&gt;




&lt;p&gt;Later, reflecting on the chaos of that day, I realised something. Handling high-pressure situations like this didn't come from my technical skills, it came from DJing in clubs in my younger days.&lt;/p&gt;

&lt;p&gt;When DJing, your time bomb resets every new song you play. Especially when you're playing &lt;em&gt;uncharted&lt;/em&gt; genres, its not bizarre to have just 30 seconds on the clock and not have a next song.&lt;/p&gt;

&lt;p&gt;You'd have to pick a song, put in a CD, cue it to the point you wanna play it, say something ridiculous to hype up the crowd, and play the next track - all as if it were deliberate and perfectly intended.&lt;/p&gt;

&lt;p&gt;There were times I had to do all of that in just about 10 seconds too.&lt;/p&gt;

&lt;p&gt;In those moments, you're not just playing music - you're a freggin' time magician, convincing everyone that &lt;em&gt;this&lt;/em&gt; is exactly what they came for.&lt;/p&gt;

&lt;p&gt;Because fundamentally, the clock aint gonna stop for no one.&lt;/p&gt;

&lt;p&gt;It's &lt;em&gt;what you do&lt;/em&gt; in that time that matters.&lt;/p&gt;




&lt;p&gt;Right in the neck that was. &lt;/p&gt;

</description>
      <category>programmingfail</category>
      <category>mongodb</category>
      <category>meteor</category>
      <category>humour</category>
    </item>
    <item>
      <title>Building a Zoomable UI with Meteor.js &amp; Greensock</title>
      <dc:creator>Jason Joseph Nathan</dc:creator>
      <pubDate>Sun, 04 Jan 2015 04:00:00 +0000</pubDate>
      <link>https://dev.to/thegeekist/building-a-zoomable-ui-with-meteorjs-greensock-40fh</link>
      <guid>https://dev.to/thegeekist/building-a-zoomable-ui-with-meteorjs-greensock-40fh</guid>
      <description>&lt;p&gt;An exploration of Zoomable User Interfaces (ZUIs) with Meteor.js and Greensock &amp;amp; a unique responsive UI design technique&lt;/p&gt;

&lt;p&gt;&lt;a href="https://geekist.co/building-a-zoomable-user-interface-with-meteor-js-greensock" rel="noopener noreferrer"&gt;Source&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tamethetech</category>
      <category>wheretheuserbegins</category>
    </item>
  </channel>
</rss>
