<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="csrf-token" content="kdBKX1AquRzJRIyI4pfhjoUnOssWxPc8NQU8ScId">

        <title>Laravel</title>

        <!-- Fonts -->
        <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap">

        <!-- Styles -->
        <link rel="stylesheet" href="https://www.mikeduncan.com/css/app.css">

        <!-- Scripts -->
        <script src="https://www.mikeduncan.com/js/app.js" defer></script>
    </head>
    <body class="font-sans antialiased">
        <div class="min-h-screen">
            <!-- Page Heading -->
<header class="flex justify-between max-w-5xl my-0 mx-auto border border-gray-300 bg-white shadow">

    <div class="justify-start mx-auto py-6 px-4 sm:px-6 lg:px-8">
        <a class="text-gray-800 underline text-lg" href="/">Home</a>
    </div>

        <div class="justify-end mx-auto py-6 px-4 sm:px-6 lg:px-8 text-right">
        <a class="text-gray-800 underline text-lg" href="/login">Login</a>
    </div>
    
</header> 



            <div id="main-wrapper" class="my-0 mx-auto h-screen ">
                <!-- Page Content -->
                <main class="flex flex-wrap flex-row max-w-5xl bg-white  my-0 mx-auto">

                    <div id="sidebar" class="w-full order-2 sm:order-1 sm:w-1/3 flex-grow border bg-gray-100 border-gray-300">
                        
  <div class="p-6">
    <p class="text-xl font-extrabold text-gray-700 mb-2">Last 5 posts</p>
    
            <div class="list-group mb-6">
        <div class="list-group-item">
            <h3 class="text-2xl font-medium text-gray-900 title-font mb-2"><a href="https://www.mikeduncan.com/efdse">efdse</a></h3>
            <div class="md:w-64 md:mb-0 mb-6 flex-shrink-0 flex flex-col">
            <span class="font-semibold title-font text-gray-700">awdawd</span>
            <span class="mt-1 text-gray-500 text-sm">Oct 18,2021 at 06:37 am</span>
            </div>

            
            <a class="text-indigo-500 inline-flex items-center mt-4" href="https://www.mikeduncan.com/efdse">Full post
            <svg class="w-4 h-4 ml-2" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
                <path d="M5 12h14"></path>
                <path d="M12 5l7 7-7 7"></path>
            </svg>
            </a>
        </div>
        </div>
            <div class="list-group mb-6">
        <div class="list-group-item">
            <h3 class="text-2xl font-medium text-gray-900 title-font mb-2"><a href="https://www.mikeduncan.com/sevagoth">Sevagoth</a></h3>
            <div class="md:w-64 md:mb-0 mb-6 flex-shrink-0 flex flex-col">
            <span class="font-semibold title-font text-gray-700">Duncan</span>
            <span class="mt-1 text-gray-500 text-sm">Apr 30,2021 at 02:59 pm</span>
            </div>

            
            <a class="text-indigo-500 inline-flex items-center mt-4" href="https://www.mikeduncan.com/sevagoth">Full post
            <svg class="w-4 h-4 ml-2" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
                <path d="M5 12h14"></path>
                <path d="M12 5l7 7-7 7"></path>
            </svg>
            </a>
        </div>
        </div>
            <div class="list-group mb-6">
        <div class="list-group-item">
            <h3 class="text-2xl font-medium text-gray-900 title-font mb-2"><a href="https://www.mikeduncan.com/test-post">Test post</a></h3>
            <div class="md:w-64 md:mb-0 mb-6 flex-shrink-0 flex flex-col">
            <span class="font-semibold title-font text-gray-700">Duncan</span>
            <span class="mt-1 text-gray-500 text-sm">Apr 30,2021 at 02:42 pm</span>
            </div>

            
            <a class="text-indigo-500 inline-flex items-center mt-4" href="https://www.mikeduncan.com/test-post">Full post
            <svg class="w-4 h-4 ml-2" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
                <path d="M5 12h14"></path>
                <path d="M12 5l7 7-7 7"></path>
            </svg>
            </a>
        </div>
        </div>
            <div class="list-group mb-6">
        <div class="list-group-item">
            <h3 class="text-2xl font-medium text-gray-900 title-font mb-2"><a href="https://www.mikeduncan.com/tammy-is-oddly-popular">Tammy is oddly popular</a></h3>
            <div class="md:w-64 md:mb-0 mb-6 flex-shrink-0 flex flex-col">
            <span class="font-semibold title-font text-gray-700">Duncan</span>
            <span class="mt-1 text-gray-500 text-sm">Apr 30,2021 at 02:00 am</span>
            </div>

            
            <a class="text-indigo-500 inline-flex items-center mt-4" href="https://www.mikeduncan.com/tammy-is-oddly-popular">Full post
            <svg class="w-4 h-4 ml-2" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
                <path d="M5 12h14"></path>
                <path d="M12 5l7 7-7 7"></path>
            </svg>
            </a>
        </div>
        </div>
            <div class="list-group mb-6">
        <div class="list-group-item">
            <h3 class="text-2xl font-medium text-gray-900 title-font mb-2"><a href="https://www.mikeduncan.com/mints-catch-phrase-is-ahhhh">Mint&#039;s catch phrase is ahhhh.</a></h3>
            <div class="md:w-64 md:mb-0 mb-6 flex-shrink-0 flex flex-col">
            <span class="font-semibold title-font text-gray-700">Duncan</span>
            <span class="mt-1 text-gray-500 text-sm">Apr 30,2021 at 12:54 am</span>
            </div>

            
            <a class="text-indigo-500 inline-flex items-center mt-4" href="https://www.mikeduncan.com/mints-catch-phrase-is-ahhhh">Full post
            <svg class="w-4 h-4 ml-2" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
                <path d="M5 12h14"></path>
                <path d="M12 5l7 7-7 7"></path>
            </svg>
            </a>
        </div>
        </div>
    
            <p><a class="text-xl underline font-extrabold text-blue-700 mb-2 "href="/show-all">See ALL posts...</a></p>
     
    </div>

  
                    </div><!-- end sidebar -->

                
                    <div id="body" class="w-full order-1 sm:order-2 sm:w-2/3 border border-gray-300 ">
                        <div class="text-xl text-gray-800 p-6" >
  <h1 class="text-2xl text-gray-700 underline">Welcome to the Proof Of Concept DuncanBlog</h1>
  <hr>
  <p class="py-3">Ok, time for a little tech talk, ... <i>so what are you looking at exactly here anyway?</i></p>
  <p class="py-3">For this use-case, this blog is built from scratch on a fresh install of Laravel 8, using Eloquent ORM againt SQLite as a DB.  I have been a fan of SQLite for quick projects forever, and in real world terms if you were building a lopsidedly read-heavy application (like a blog), the performance would be as good as the standard options even up to a pretty significant traffic load.  For this project it made sense as a way to build and commit the entirety of the project into source control without extra dependecies.</p>  
  <p class="py-3">The routes are mostly what you would expect, although I did recycle one route using GET vs POST for different actions.</p>  
  <p class="py-3">Since I had not had the excuse to learn it before, I took the opportunity to setup all the styling using <a class="text-blue-500 underline" target="_blank" href="https://tailwindcss.com/">Tailwind CSS</a>.  This compositional CSS system is a most-favored-nation in modern Laravel develoment but at the same time is often a devisive topic among CSS purists.  I'll admit there is a kind of <i>"wait you shouldn't be doing this"</i> dissonance the first time around different with this approach, but after having learned enough of it to create this blog, I'm can see it's place, particularly in prototyping or while working in component-centric frameworks to begin with.  Pretty cool.</p>  
  <p class="py-3">The WYSIWYG interface in the blog admin is using <a class="text-blue-500 underline" href="https://quilljs.com/" target="_blank">QuillJS.</a>.  I had never used it before but it's pretty capable and has a kind of API-driven design to it.  Out of the box it can serialize the input into json entities vs. only ending up with HTML as the output (although not really needed in our use case).</p>
  <p class="py-3">All of this is running on an <a class="text-blue-500 underline" href="https://aws.amazon.com/lightsail/" target="_blank">AWS LightSail</a> Ubuntu 20.04 instance I spun up, and installed php / apache on.  LightSail is AWS's canned EC2 instances offering where you get turnkey streamlined EC2 boxes with fewer options but quick and easy admin.  Great for ephemeral / proof of concept machines.</p>
  <p class="py-3">Since the nature of this exercise is to show the work related in routing, CRUD operations, etc, 
    I wrote the classes by hand and only tapped into one common starter package which 
    is <a class="text-blue-500 underline" href="https://github.com/laravel/breeze"  target="_blank">Laravel Breeze</a> (nicer-looking auth than the built in auth classes.).</p>
  <h2 class="my-3 font-bold">Ok, so if this weren't an exercise how would this have been approached differently?</h2>
  <h3 class="font-bold">Option 1</h3>
  <p  class="py-3">If the task at hand was simply to standup a Laravel-powered blog for production use, I would have taken this in a different direction.  If we were going to use a standard database-driven solution I would have implemented <a class="text-blue-500 underline" href="https://www.getcraftable.com/"  target="_blank">Craftable</a> (open source) which gets you very nice CRUD / Admin interface "for free".  It scaffolds out against your Model classes and you end up with a very user friendly Admin interface ready to go complete with WYSIWYG interface, and Media Gallery capabilites.  This particular site could have been built in easily 1/2 the time with this option.</p>
  <h3 class="my-3 font-bold">Option 2</h3>
  <p class="py-3">If we are more generally just looking for a standalone Laravel powered blog, I would have checked out <a class="text-blue-500 underline" href="https://jigsaw.tighten.co/"  target="_blank">Jigsaw</a>.  Jigsaw is a Laravel-powered static site generator which is a great modern workflow that lends itself to simple deploys and almost unlimited easy-scaling. This is something I've been meaning to run a proof of concept through for a while.<p> 
  <h3 class="my-3 font-bold">Follow on Questions / Other Considerations...</h3>
  <h3 class="my-3 font-bold">How does the system operate if the Backend is hosted on a different server from the Frontend/Admin?</h3>
  <p  class="py-3">So in this case with SQLite you are kind of stuck.  If we wan't to switch to MySql, we can update connection type and re-migrate our models into MySql's schema, though we would need to write a custom bit to move the data around.</p>
  <h3 class="my-3 font-bold">Where might you apply caching to avoid overwhelming the database during high traffic?</h3>
  <p  class="py-3">Static assets can be cached in a CDN, data driven performance could be beefed up by throwing an in memory cache at it like memcached or redis.  You would retool some code for cache invalidation, etc. Alternately you can scale horizontally if you have cloud-based auto scaling servers / container services behind a load balancer.  Spin up time still takes a few minutes per onboarded node, but the upside is this is a more or less infinitely scalable solution.</p>
  <h3 class="my-3 font-bold">Expand the admin tool to allow updates of posts and deleting posts.</h3>
  <p  class="py-3">I threw in a couple additional routes / pages for 1) editing existing pages (must be logged in and on details page) and 2) Viewing a master list of <a class="text-blue-500 underline" href="/show-all">All</a> pages in the system.</p>
  <h3 class="my-3 font-bold">Allow uploading of a high-resolution image to be displayed on the article page that is automatically resized for the home page thumbnail.</h3>
  <p  class="py-3">Right now I'm accepting in and displaying the uploaded assets responsively but large-ish on the blog details page.  If you visit the <a class="text-blue-500 underline" href="/show-all">Show All</a> page, you will see the images further thumbnailed.
    (This is css container fitting, not running through a true image resizer).</p>

    
</div>
                    </div>
                    
                    
                </main>
            </div> <!-- main wrapper -->
        </div>
    </body>
</html>
