Chris Padilla/Blog

My passion project! Posts spanning music, art, software, books, and more
You can follow by Newsletter or RSS! (What's RSS?) Full archive here.

    Restoring 4 Hearts

    Yum!

    We haven't found the recipe for Ice Cream Cookie Sandwiches in Tears of the Kingdom yet!

    Strauss - Blue Danube Waltz

    Listen on Youtube

    🚀 🪐

    Too late for the Space Odyssey reference in the Barbie move?

    Moblin Mask

    The way it flops! 😂

    I just think this Moblin hat in Tears of the Kingdom is swell.

    New Blog Layout and Pagination

    I've updated my blog home page to show posts in full instead of just the titles. I'm doing too much art and music making to let all that fun stuff hide behind a click!

    I also found out I've posted over 200 times to this blog!! A great milestone! And a fun performance issue to navigate with pagination. :)

    Hey Diglett!

    Pagination

    In a big picture sense, you need these things:

    • Loads of data to render, like blog posts
    • A way to query it
    • A maximum number per page (the interval at which to show data)
    • A way to keep track of which page you're on.

    That translates to:

    • Content
    • API/DB Calls
    • Limit value
    • Skip value

    Calculating Skip

    Skip value is the most interesting value up there. If you have a limit of 5 posts per page, you'll know your starting place if you know what page you're on. Page 1 will shows items 0-4, so there's no skip.

    Page 2, however, starts at 5. So we can get this for each page by multiplying the page number minus 1 by 5.

    const skip = limit * (page - 1)

    From there, passing that to the DB will get you just the data you need.

    Getting Page State

    Plenty of ways to do it, though the most user friendly is likely to keep it in your query params. Your url will look something like /blog?p=2. It has the benefit of allowing users to use the back button on their browser.

    Here's how you can get that value in getServerSideProps in Next:

    export async function getServerSideProps(context) {
      const page = context.query.p || 1;
      const count = getPostsCount();
    
      const skip = (page - 1) * 5;
      const allPosts = getAllPosts(
        {
          skip,
          limit: 5,
        }
      );
    
      return {
        props: { allPosts },
      };
    }

    context is passed from next with the query params (including any that you set yourself through the [id].js naming convention.) Very handy!

    Setting Page State

    It's as simple as linking to the new url! First I'll get the current page through the client side router:

    import { useRouter } from 'next/router';
    
    export default function Blog({ allPosts, count }) {
      const router = useRouter();
      const query = router.query;
      const currentPage = parseInt(query.p) || 1;
      const lastPage = Math.ceil(count / 5);

    And then I can use it in my links below.

    <div className="pagination-controller" style={{ display: 'flex' }}>
      <div className="left" style={{ flex: '1' }}>
        {currentPage !== 1 && (
          <Link href={`${router.pathname}?p=${currentPage - 1}`}>Back</Link>
        )}
      </div>
      <div className="right" style={{ flex: '1', textAlign: 'right' }}>
        {currentPage < lastPage && (
          <Link href={`${router.pathname}?p=${currentPage + 1}`}>Next</Link>
        )}
      </div>
    </div>

    You'll have to do the math to add or reduce a page while ensuring you're not going out of bounds. Above I'm hiding the links based on the calculated lastPage.

    Neil Gaiman on Writing

    Several great nuggets of writing insight from Neil Gaiman's introduction to the 10th Anniversary Edition of American Gods.

    Storm's coming...

    Like Carl Barks, Gaiman started with a locale:

    A couple of weeks later, my editor sent me a mock-up of the book cover. It showed a road, and a lightning strike, and, at the top, it said, “American Gods.” It seemed to be the cover of the book I had planned to write.

    I found it both off-putting and exhilarating to have the cover before the book. I put it up on the wall and looked at it, intimidated, all thoughts of ever finding another title gone forever. This was the book cover. This was the book.

    Now I just had to write it.

    I think about this often, because it feels so true. Each project really does take it's own path:

    I remember when it was all done in first draft telling Gene Wolfe, who is the wisest writer I know and has written more excellent novels than any man I’ve met, that I thought I had now learned how to write a novel. Gene looked at me, and smiled kindly. “You never learn how to write a novel,” he told me. “You only learn to write the novel you’re on.”

    And then, of course, a great reminder to ship imperfection:

    I finished it, eventually, and I handed it in, taking a certain amount of comfort in the old saying that a novel can best be defined as a long piece of prose with something wrong with it, and I was fairly sure that I’d written one of those.