Reader small image

You're reading from  Angular Projects - Third Edition

Product typeBook
Published inJul 2023
Reading LevelIntermediate
PublisherPackt
ISBN-139781803239118
Edition3rd Edition
Languages
Tools
Right arrow
Author (1)
Aristeidis Bampakos
Aristeidis Bampakos
author image
Aristeidis Bampakos

Aristeidis Bampakos is a Web Development Team Lead at Plex-Earth who specializes in the development of web applications with Angular. He has been an Angular Google Developer Expert (GDE) since 2020 and works as an Angular Senior Tech Instructor at Code.Hub, a private educational institute, where he nurtures aspiring Angular developers and professionals. He is also the author of Angular Projects with Packt.
Read more about Aristeidis Bampakos

Right arrow

Displaying blog posts on the home page

We would like our users to see the list of available blog posts as soon as they land on our blog website. According to the default route path that we have defined, ArticlesComponent is the landing page of our blog. Scully provides ScullyRoutesService, an Angular service that we can use in our components to get information about the routes that it will create according to the blog posts. Let’s put this service into action on our landing page:

  1. Open the articles.component.ts file and modify the import statements as follows:
    import { Component, OnInit } from '@angular/core';
    import { ScullyRoute, ScullyRoutesService } from '@scullyio/ng-lib';
    import { Observable, map } from 'rxjs';
    
  2. Add the OnInit interface to the list of implemented interfaces of the ArticlesComponent class:
    export class ArticlesComponent implements OnInit {
    }
    
  3. Inject ScullyRoutesService in the constructor of the ArticlesComponent class:
    constructor(private scullyService: ScullyRoutesService) { }
    
  4. Create the following component property:
    posts$: Observable<ScullyRoute[]> | undefined;
    
  5. Implement the ngOnInit method:
    ngOnInit(): void {
      this.posts$ = this.scullyService.available$.pipe(
        map(posts => posts.filter(post => post.title))
      );
    }
    
  6. Open the articles.component.html file and add the following HTML code:
    <div class="list-group mt-3">
      <a *ngFor="let post of posts$ | async"
        [routerLink]="post.route" class="list-group-item
          list-group-item-action">
        <div class="d-flex w-100 justify-content-between">
          <h5 class="mb-1">{{post.title}}</h5>
        </div>
        <p class="mb-1">{{post['description']}}</p>
      </a>
    </div>
    

There are many Angular techniques involved in the previous steps, so let’s break them down piece by piece.

When we want to use an Angular service in a component, we just need to ask for it from the Angular framework. How? By adding it as a property in the constructor of the component. The component does not need to know anything about how the service is implemented.

The ngOnInit method is part of the OnInit interface, which is implemented by our component. It is called by the Angular framework when a component is initialized and provides us with a hook to add custom logic to be executed.

Angular services that provide initialization logic to a component should be called inside the ngOnInit method and not in the constructor because it is easier to provide mocks about those services when unit testing the component.

The available$ property of ScullyRoutesService is called an observable and returns all the available routes that were generated from Scully when we subscribe to it. To avoid displaying routes other than those related to blog posts, such as the contact route, we filter out the results from the available$ property.

In the component template, we use the *ngFor Angular built-in directive and the async pipe to subscribe to the posts$ observable inside HTML. We can then access each item using the post template reference variable and use interpolation to display title and description.

Finally, we add a routerLink directive to each anchor element to navigate to the respective blog post when clicked. Notice that routerLink is surrounded by []. The [] syntax is called property binding, and we use it when we want to bind the property of an HTML element to a variable. In our case, we bind the routerLink directive to the route property of the post variable.

Now that we have finally completed all the pieces of the puzzle, we can see our blog website in action:

  1. Run the build command of the Angular CLI to build our Angular application:
    ng build
    
  2. Execute the following command to build Scully and generate our blog routes:
    npx scully --project my-blog
    

    The preceding command will create a scully-routes.json file inside the src\assets folder. It contains the routes of our Angular application and is needed by the Scully runtime.

    Running the Scully executable for the first time will prompt you to collect anonymous errors to improve its services.

  1. Run the following command to serve our blog:
    npx scully serve --project my-blog
    

The preceding command will start two web servers: one that contains the static prerendered version of our website built using Scully and another that is the Angular live version of our application:

Figure 2.5 – Serving our application

If we open our browser and navigate to http://localhost:1668, we will not see any blog posts. A blog post created with Scully is not returned in the available$ property of ScullyRoutesService unless we publish it. To publish a blog post, we do the following:

  1. Navigate to the mdfiles folder that Scully created and open the only .md file that you will find. The name and contents may vary for your file because it is based on the date Scully created it:
    ---
    title: 2023-06-22-posts
    description: 'blog description'
    published: false
    slugs:
        - ___UNPUBLISHED___lj738su6_7mqWyfNdmNCwovaCCi2tZItsDKMPJGcG
    ---
    # 2023-06-22-posts
    

    Scully has defined a set of properties between the closing and ending --- lines at the top of the file representing metadata about the blog post. You can also add your own as key-value pairs.

  1. Delete the slugs property and set the published property to true:
    ---
    title: 2023-06-22-posts
    description: 'blog description'
    published: true
    ---
    # 2023-06-22-posts
    
  2. Run the following command to force Scully to regenerate the routes of our application:
    npx scully --project my-blog
    

    We need to execute the previous command every time we make a change in our blog-related files.

  1. Execute the npx scully serve --project my-blog command and navigate to preview the generated website.

We can now see one blog post, the default one that was created when we installed Scully. Let’s create another one:

  1. Run the following generate command of the Angular CLI:
    ng generate @scullyio/init:post --name="Angular and Scully"
    

    In the preceding command, we use the @scullyio/init:post schematic, passing the name of the post that we want to create as an option.

  1. Set the target folder for the new blog post to mdfiles:
    What's the target folder for this post? (blog)
    
  2. Scully will create a Markdown file named angular-and-scully.md inside the specified folder. Open that file and update its content to be the same as the following:
    ---
    title: 'Angular and Scully'
    description: 'How to build a blog with Angular and Scully'
    published: true
    ---
    # Angular and Scully
    Angular is a robust JavaScript framework that we can use to build excellent and performant web applications.
    Scully is a popular static website generator that empowers the Angular framework with Jamstack characteristics.
    You can find more about them in the following links:
    - https://angular.io
    - https://scully.io
    - https://www.jamstack.org
    
  3. Run npx scully --project my-blog to create a route for the newly created blog post. Scully will also update the scully-routes.json file with the new route.

If we preview our application now, it should look like the following:

Εικόνα που περιέχει κείμενο, στιγμιότυπο οθόνης, γραμματοσειρά, γραμμή  Περιγραφή που δημιουργήθηκε αυτόματα

Figure 2.6 – List of blog posts

If we click on one of the blog items, we will navigate to the selected blog post. The content that is currently shown on the screen is a prerendered version of the blog post route:

Εικόνα που περιέχει κείμενο, στιγμιότυπο οθόνης, γραμματοσειρά  Περιγραφή που δημιουργήθηκε αυτόματα

Figure 2.7 – Blog post details

To verify that, navigate to the dist folder of your Angular project, where you will find two folders:

  • my-blog: This contains the Angular live version of our application. When we execute the ng build Angular CLI command, it builds our application and outputs bundle files in this folder.
  • static: This contains a prerendered version of our Angular application generated from Scully when we run the npx scully --project my-blog command.

If we navigate to the static folder, we will see that Scully has created one folder for each route of our Angular application. Each folder contains an index.html file, which represents the component that is activated from that route.

The contents of the index.html file are auto-generated by Scully, and behave as if we run our application live and navigate to that component.

Now you can take your Angular application, upload it to the CDN or web server of your choice, and you will have your blog ready in no time! All you will have to do then will be to exercise your writing skills to create excellent blog content.

Previous PageNext Page
You have been reading a chapter from
Angular Projects - Third Edition
Published in: Jul 2023Publisher: PacktISBN-13: 9781803239118
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
Aristeidis Bampakos

Aristeidis Bampakos is a Web Development Team Lead at Plex-Earth who specializes in the development of web applications with Angular. He has been an Angular Google Developer Expert (GDE) since 2020 and works as an Angular Senior Tech Instructor at Code.Hub, a private educational institute, where he nurtures aspiring Angular developers and professionals. He is also the author of Angular Projects with Packt.
Read more about Aristeidis Bampakos