Blog Post Page

04 December 2019
Alright! Let’s talk about more than 4 lines of code this time. We have been taking a break from coding and writing for a bit. Slowly easing back into it. Rest time is important, next time we just need to find a better balance. Oh but heads up, next week our mom is coming in for like 2.5 weeks and we will have our child over for like a week and a half this month, probably going to miss a few days here and there :3 Okay so first up, let’s start with the navigation!

<BSPagination Class="paging fixed-top mx-5">
<BSPaginationItem IsDisabled="@(Previous == null ? true : false)">
<BSPaginationLink PaginationLinkType="PaginationLinkType.PreviousText" Href="@GetUrl("Previous")" />
</BSPaginationItem>
<BSPaginationItem IsDisabled="@(Next == null ? true : false)">
<BSPaginationLink PaginationLinkType="PaginationLinkType.NextText" Href="@GetUrl("Next")" />
</BSPaginationItem>
</BSPagination>
Okay so you might be wondering what weird HTML tags these are. So blazor app works by having components that other components can call with xml/html syntax. We will go into that deeper for a different page, but for these tags, the ones starting with BS, are from an open source blazer app package called BlazorStrap, and yes we chuckle at the name sometimes too. Basically it makes blazor components that map to bootstrap. So it just makes it a little nicer to use.

That out of the way, what is this chunk of html doing. Well Class is the same from html, basically that’s what is keeping it to the top of the page. Next disabled or not is based on either Previous or Next, we will cover those further down the page, but basically if it’s set, have the button on, if not, have the button off. PaginationLinkType is basically just a static string constant. Then GetUrl uhhh gets the url.

<base href="~/" />
<h3 class="ml-5">@Blog.Title</h3>
<small class="ml-5">@Blog.DateAdded.ToString("dd MMMM yyyy")</small>
<div class="m-5">
@((MarkupString)Blog.Post)
</div>

That first line should be moved above the paging, it’s boilerplate stuff we need to make somethings work, it should be moved to a parent component. Next the title of the blog, just slap a header tag and move it in a bit. Next date added, we use tostring to format it. Then the post itself, convert it to markupstring so html will work.

@code {
[Parameter]
public int Id { get; set; }
[Parameter]
public string Type { get; set; }
private Blog Blog;
private int? Next;
private int? Previous;

Alright now to some code! So the parameter tag, if you remember from last post, line up with the input parms. The rest are pretty self explaining. int? means they are nullable. Okay so these variables give us a pretty good idea of what is going on already. Id is the id for the blog post in the DB, Type is for knowing what type of blog should be next/previous. And Next/Previous are ids for just that.

    protected override void OnInitialized() {
SetUpNextAndPrevious();
NavManager.LocationChanged += OnLocationChanges;
}

protected override async Task OnAfterRenderAsync(bool firstRender) {
await JSRuntime.InvokeAsync<string>("PR.prettyPrint");
}

public void Dispose() {
NavManager.LocationChanged -= OnLocationChanges;
}

private void OnLocationChanges(object sender, LocationChangedEventArgs e) => SetUpNextAndPrevious();

Okay so this isn’t the order we have them on in the code, all of these methods besides OnInitalized are at the bottom of the file. Last time we talked about IDisposable, well this is where it comes into play. OnInit(ialized) is the entry point of the file, so we have it at the top. So let’s walk though what happens from init to the code running.

Page is navigated to.
Parameters are parsed automatically from the url.
OnInit is called
Calls the setup method
Add a delegate to the LocationChanged event
Now that event points to the setup method
The html is generated
OnAfterRender is called
Call pretty print for code syntax highlighting
//TODO: add list to bbcode parser
Okay cool got it? Oh and the dispose method is just called when this page is fully left. Part of the event auto called by the system cause this file uses IDisposable, just unsubscribing from the event. As we said last time, it’s all boilerplate code that could and should be moved to a parent layout. But it does lead nicely into the setup method!

    private void SetUpNextAndPrevious() {
var nextPrevious = BlogDataService.GetBlogNextAndPrevious(Id, Type);
Next = nextPrevious[];
Previous = nextPrevious[];
Blog = BlogDataService.GetBlogFull(Id);
StateHasChanged();
}

Okay, we get back an array from the DB. Remember, a custom service in our system is a static singleton file. We use it just to get info from the server. The first two indexes will always be set, even if null so we can just slap those bad boys into Next and Previous. Then we get the blog from the DB, and call StateHasChanged to refresh what’s on this page. So we already said that the setup is called before the HTML is rendered, so why refresh the state? Well thanks for asking

    private string GetUrl(string direction) {
var index = "";
if (direction == "Next" && Next != null)
index = "/" + Next;
else if (direction == "Previous" && Previous != null)
index = "/" + Previous;
var type = "";
if (Type != null)
type = "/" + Type;
return "/blog" + index + type;
}

So earlier in the page we called GetUrl, for a href value on a link. Basically we are using a string as a boolean value. Might be better to do bool isNext or something. So really all it is doing is getting Next/Previous and attaching it to a string to link to the next/previous post. Including the type if it’s set. So this is why we have to refresh the state and keep track of the location changed event. The next/previous button navigates back to this page.

We will be moving this code so blah blah, it’s bad design. From what we know, this has to happen at some point in the code if you want a page to navigate back to itself, but could be totally wrong. But that’s basically it for the post page! One of the more simpler pages, but we don’t really plan on covering every page. This has been more an exercise in explaining how blazor app works and how you can us it to pull a lot of logic away from the front end.

Alright everyone, we should see you all tomorrow~~