Site Update: Editable Title and Link on Site Logo

Our latest updates early this December is quite extensive. Starting with minor updates such as addition of footer, and change of our nav-logo from just an ordinary image into an image link pointing to landing page, we also have the following major changes:

  1. Pagination now just works.
  2. Title can be edited via PUT: /posts/{uuid}/updatetitle route.
  3. Recent Blog Posts is now available on our secondary panel.

Let’s explore them one by one.

Pagination

Pagination is not as hard as we previously imagined. It was actually quite straightforward, and is as simple as replacing:

$posts = Post::select('posts.id','posts.title')
         ->orderBy('created','desc')
         ->get();

Into as follows:

$posts = Post::select('posts.id','posts.title')
         ->orderBy('created','desc')
         ->paginate(15);

You can read more about pagination in Laravel’s official documentation. Basically we have to ensure that when sending variables to our views, we have to also send the instance of Illuminate\Pagination\LengthAwarePaginator (when using paginate method) to our views. Then we can use that instance to generate necessary components. In Laravel’s official documentation, it is said that to display the paginator we can simply use {{$posts->links()}}, and it would result in a view that is compatible for Tailwind CSS framework.

It turns out, displaying the pagination links is not as straightforward in our case. As you may have guessed, our site’s interface is purely HTML, CSS, and Javascript, not in Tailwind CSS. Therefore it is necessary for us to recreate necessary components to have a basic pagination.

The first thing we did on our Blade template was to get all the necessary values I might need into a number of variables:

@php
    $prevPageURL = $paginator->previousPageUrl();
    $currPage = $paginator->currentPage();
    $currPageURL = $paginator->url($currPage);
    $nextPageURL = $paginator->nextPageurl();
    $lastPage = $paginator->lastPage();
    $postsCount = $paginator->total();
@endphp

Our pagination appearance starts with something as follows:

36 news items, viewing page 1 of 3.

We can easily use our variables as follows:

{{$postsCount}} news items, viewing page {{$currPage}} of {{$lastPage}}.

Then following it is a set of links:

<prev 1 2 3 4 5 next>

In HTML it is written as something like:

<a href="#">&lt;prev</a>
<a href="#">1</a>
<a href="#">2</a>
3 <!-- the current page -->
<a href="#">4</a>
<a href="#">5</a>
<a href="#">next&gt;</a>

For our <prev link, we would refer its href to $prevPageURL. Respectively, our next> link is directed toward $nextPageURL. The current page indicator would not be made into a link.

Meanwhile, we can get the links of all other pages but the current page with $paginator->url() function. It takes the page number as an argument, and it would return a link to said page number. We can put them in a for loop, and for example, if the index of our for loop is $i, then we can just invoke it with $paginator->url($i), and we get our link.

Edit Title

We have prepared a new PUT route: /posts/{uuid}/updatetitle that will accept text input with ID and name: title

It would then be processed with the following function under PostController:

public function updateTitle(Request $request, $id)
{
    $validated = $request
        ->validate([
            'title' => 'required|unique:posts|max:255',
        ]);
    $post = Post::find($id);
    $post->title = $request->input('title');
    $post->slug = Str::slug($post->title, '-');
    $post->save();
    return back()->withInput();
}

Basically the function only checks if there is a new unique title provided to it or not. It would then add the post’s slug so that it can be accessed by guests.

For completion purposes, the edit title button would be included in our Post Edit Form. It is implemented as a separate form on the secondary panel.

Recent Blog Posts

The secondary panel at our landing page is meant to be showing a list of recent blog posts. We already have something like our latest news, where we fetch a number of published posts of type news, and list them according to a set of rules. We basically did the same for blog posts, where we fetch a number of published posts of type blog.

We also experimented with the use of AppServiceProvider.php to provide $latestNews and $recentPosts alongside with our $navbars on all of our views. It removes the need for us to pass the data manually from DummyController method home().

We are aware that this method is not efficient, and we are currently devising a more resource-efficient approach for this. However we like the simplicity of this current method.

API Endpoint Changes and Alternative viewer.

We add blogs key under data.feed of our output JSON (from route /api/home), therefore our alternative viewer could display the content of secondary panel properly.

Our alternative viewer is present when you are accessing nonexistent subdomain (such as https://blabla.liecorp.id). A viewer with superficial similarity to our landing page would be loaded. The content of that page is fully served using javascript, instead of using blade templating on our actual landing page.