Creando un Blog Dinámico con ButterCMS, Angular

En la era digital actual, tener un blog es fundamental para cualquier sitio web que busque aumentar su visibilidad y comprometer a su audiencia. En este post, te guiaré a través de los pasos para crear un blog dinámico utilizando ButterCMS como sistema de gestión de contenido, Angular como framework de desarrollo front-end y la moderna plantilla Logbook de Bootstrap.

Creación de un nuevo proyecto Angular utilizando Angular CLI.

Para crear un nuevo proyecto Angular utilizando Angular CLI, sigue estos pasos:

Instala Angular CLI (si aún no lo has hecho):

Abre tu terminal y ejecuta el siguiente comando para instalar Angular CLI de forma global en tu sistema:

npm install -g @angular/cli

Crea un nuevo proyecto Angular:

Una vez instalado Angular CLI, puedes crear un nuevo proyecto Angular ejecutando el siguiente comando en tu terminal: 

ng new nombre-del-proyecto

Reemplaza "nombre-del-proyecto" con el nombre que desees para tu proyecto. Este comando generará una nueva carpeta con la estructura inicial de un proyecto Angular y descargará todas las dependencias necesarias.

Configura las opciones del proyecto:

Durante el proceso de creación del proyecto, Angular CLI te hará algunas preguntas para configurar las opciones de tu proyecto, como si deseas agregar Angular routing, qué estilo CSS deseas utilizar, etc. Puedes elegir las opciones que mejor se adapten a tus necesidades o simplemente presionar Enter para aceptar las opciones predeterminadas.

Accede al directorio del proyecto:

Una vez que se haya creado el proyecto, accede al directorio recién creado ejecutando el siguiente comando:

cd nombre-del-proyecto

Ejecuta la aplicación:

Una vez en el directorio de tu proyecto, puedes ejecutar la aplicación Angular con el siguiente comando: 

ng serve

Esto iniciará el servidor de desarrollo de Angular y podrás ver tu aplicación en el navegador en la dirección http://localhost:4200/.

¡Y eso es todo! Ahora tienes un nuevo proyecto Angular listo para ser desarrollado. 

Instalar Bootstrap

Utiliza npm para instalar Bootstrap en tu proyecto Angular. Abre una terminal y ejecuta el siguiente comando:

npm install bootstrap

Agregar estilos CSS de Bootstrap:

Después de instalar Bootstrap, necesitas agregar los estilos CSS de Bootstrap a tu proyecto. Puedes hacerlo de varias formas:

Importar estilos globalmente:

En el archivo styles.css (ubicado en la carpeta src de tu proyecto), agrega la siguiente línea para importar los estilos de Bootstrap:

@import '~bootstrap/dist/css/bootstrap.min.css';

Importar estilos en un componente específico:

Si prefieres importar los estilos de Bootstrap solo en un componente específico, puedes hacerlo agregando la importación en el archivo CSS del componente. 

Agregar scripts de Bootstrap (opcional):

Si planeas utilizar componentes de JavaScript de Bootstrap, como modales o botones de colapso, también necesitarás agregar los scripts de Bootstrap. Para hacerlo, puedes instalar jquery y popper.js a través de npm: 

npm install jquery popper.js

Luego, importa estos scripts en tu proyecto Angular. Una buena práctica es agregarlos en el archivo scripts del archivo angular.json:

"scripts": [
  "node_modules/jquery/dist/jquery.min.js",
  "node_modules/popper.js/dist/umd/popper.min.js",
  "node_modules/bootstrap/dist/js/bootstrap.min.js"
]

Verificar la integración:

Una vez que hayas seguido estos pasos, Bootstrap debería estar integrado en tu proyecto Angular. Puedes verificarlo creando un componente o modificando uno existente y utilizando clases de Bootstrap en el HTML para ver si los estilos se aplican correctamente.

Descargar la plantilla a usar

Ahora que has configurado tu proyecto Angular y estás listo para integrar la plantilla, es hora de descargarla. Para este proyecto, elegí la plantilla Logbook de la página ThemeFisher, la cual es gratuita y está disponible en el sitio web. Sin embargo, es importante destacar que tienes la libertad de utilizar la plantilla que mejor se adapte a tus necesidades y preferencias. Existen numerosas plantillas disponibles en línea, tanto gratuitas como de pago, que puedes explorar y utilizar en tu proyecto. Lo importante es encontrar una plantilla que cumpla con tus requisitos de diseño y funcionalidad, y que te ayude a alcanzar tus objetivos de manera efectiva. ¡Siéntete libre de explorar y experimentar con diferentes plantillas para encontrar la que mejor se adapte a tu visión para tu blog! 

Estructura del Proyecto Angular:

Para este proyecto, hemos definido una estructura organizada que nos ayudará a mantener nuestro código limpio y modular. Aquí está la estructura del proyecto:

├── app
│   ├── about-author
│   ├── app-shell
│   │   ├── article
│   │   ├── aside
│   │   ├── categories
│   │   ├── footer
│   │   ├── latest-post
│   │   ├── navbar
│   │   ├── post-information
│   │   ├── search
│   │   ├── previous-next
│   │   ├── tags
│   │   ├── type-search
│   ├── index
│   ├── individual-post
│   ├── models
│   ├── pipes
│   ├── services

En esta estructura, cada carpeta y componente está diseñado para cumplir una función específica en nuestro blog Angular. Desde la sección de "About the Author" hasta el "App Shell" que define la estructura general de nuestra aplicación, cada elemento está cuidadosamente organizado para facilitar el desarrollo y la mantenibilidad de nuestro proyecto.

Inicio del proyecto

El archivo app.component.html es un componente esencial en nuestra aplicación Angular. Define la estructura básica y el diseño de nuestra aplicación, proporcionando la disposición inicial que se utilizará en todas las páginas y vistas.

En este archivo, encontramos los elementos principales que componen nuestra interfaz de usuario y que se mostrarán en todas las páginas de nuestro sitio web. 

<app-navbar></app-navbar>
<router-outlet></router-outlet>
<app-footer></app-footer>

Barra de Navegación (<app-navbar></app-navbar>):

Este componente representa la barra de navegación de nuestra aplicación. La barra de navegación es una parte crucial de la interfaz de usuario, ya que proporciona enlaces y opciones de navegación que permiten a los usuarios moverse fácilmente entre las diferentes secciones de nuestro sitio web.

import { Component, ElementRef, ViewChild, viewChild } from '@angular/core';
import { MenuModel } from '../../models/menu-model';
import { RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
import { MenuService } from '../../services/menu.service';
import { Behavior } from 'popper.js';
import { BehaviorSubject } from 'rxjs';
import { SearchService } from '../../services/search.service';

@Component({
  selector: 'app-navbar',
  standalone: true,
  imports: [
    RouterModule,
    CommonModule
  ],
  templateUrl: './navbar.component.html',
  styleUrl: './navbar.component.css'
})
export class NavbarComponent {
 
  modal: boolean = false;
  menus: MenuModel[];
  @ViewChild('searchquery') search!: ElementRef;
  constructor(private menuService: MenuService, private searchService: SearchService) {
    this.menus = this.menuService.getMenus();
  }
  abrirModal() {
    this.modal = true;
    this.search.nativeElement.value = '';
    setTimeout(() => {
      this.search.nativeElement.focus();
    }, 400);
  }

  cerrarModal() {
    this.search.nativeElement.value = '';
    this.modal = false;
    this.busquedaGeneral('');
  }

  busquedaGeneral(text: string) {
    this.searchService.setFilterText(text);
  }
}
El archivo HTML define la estructura visual de la barra de navegación. Contiene elementos como el logotipo de la aplicación, los menús de navegación, el campo de búsqueda y el modal de búsqueda.
<header class="sticky-top bg-white border-bottom border-default">
  <div class="container">
    <nav class="navbar navbar-expand-lg navbar-white">
       <a class="navbar-brand" href="">
        <img src="assets/logo_trial_pe.png" width="200px">
       </a>
       <button class="navbar-toggler border-0" type="button" data-toggle="collapse" data-target="#navigation">
          <i class="ti-menu"></i>
       </button>

       <div class="collapse navbar-collapse text-center" id="navigation">
          <ul class="navbar-nav ml-auto">
            @for (menu of menus; track $index) {
              <li class="nav-item">
                <a class="nav-link" [routerLink]="[menu.link]" [routerLinkActive]="['active']" >{{menu.title}}</a>
             </li>
            }
          </ul>
          <!-- search -->
          <div class="search px-4">
             <button id="searchOpen" class="search-btn" (click)="abrirModal();"><i class="ti-search"></i></button>
             <div class="search-wrapper" [ngClass]="{'open': modal}" #wrapper>
                <form action="javascript:void(0)" class="h-100">
                   <input class="search-box pl-4" id="search-query" #searchquery name="s" type="search" placeholder="Type &amp; Hit Enter..." (keyup.enter)="busquedaGeneral(searchquery.value);">
                </form>
                <button id="searchClose" #wrapperclose class="search-close" (click)="cerrarModal()"><i class="ti-close text-dark"></i></button>
             </div>
          </div>
       </div>
    </nav>
  </div>
  </header>
  <!-- /navigation -->

Área de Contenido Dinámico (<router-outlet></router-outlet>):

Este elemento <router-outlet> es donde se cargarán dinámicamente los componentes específicos de cada página en función de la URL actual. Es parte fundamental del enrutamiento de Angular y nos permite crear una experiencia de navegación fluida y sin problemas para nuestros usuarios.

Pie de Página (<app-footer></app-footer>):

Este componente representa el pie de página de nuestra aplicación. El pie de página es una sección importante que suele contener información adicional, enlaces útiles y atribuciones de derechos de autor. Proporciona una forma de completar la experiencia del usuario y asegura que nuestro sitio web sea completo y bien presentado.

import { Component } from '@angular/core';
import { MenuModel } from '../../models/menu-model';
import { MenuService } from '../../services/menu.service';
import { AuthorModel } from '../../models/author-model';
import { ButterService } from '../../services/butter.service';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-footer',
  standalone: true,
  imports: [
    CommonModule
  ],
  templateUrl: './footer.component.html',
  styleUrl: './footer.component.css'
})
export class FooterComponent {
scrollToTop() {
    window.scrollTo({ top: 0, behavior: 'smooth' });
}
  menus: MenuModel[];
  author!: AuthorModel;
  constructor(private menuService: MenuService, private butter: ButterService) {
    this.menus = this.menuService.getMenus();
    this.butter.getAuthor('vladimir-miranda').subscribe((resp: any) => {
      this.author = resp.data;
    });
  }
}

El archivo HTML define la estructura visual del pie de página. Contiene elementos como el logotipo de la aplicación, información sobre el blog, menús de navegación, enlaces sociales, formulario de suscripción y atribuciones de derechos de autor. 

<footer class="section-sm pb-0 border-top border-default">
  <div class="container">
    <div class="row justify-content-between">
      <div class="col-md-3 mb-4">
        <a class="mb-4 d-block" href="index.html">
          <img
            class="img-fluid"
            width="150px"
            src="images/logo.png"
            alt="Programacion Ecuador"
          />
        </a>
        <p>
          "Programación Ecuador" es un blog dedicado al desarrollo de software en Ecuador. En él, exploramos diversos temas relacionados con la programación, desde tutoriales y guías prácticas hasta análisis de tendencias y noticias relevantes en el mundo de la tecnología.
        </p>
      </div>

      <div class="col-lg-2 col-md-3 col-6 mb-4">
        <h6 class="mb-4">Menu</h6>
        <ul class="list-unstyled footer-list">
          @for (menu of menus; track $index) {
            <li><a [href]="menu.link">{{menu.title}}</a></li>
          }
        </ul>
      </div>

      <div class="col-lg-2 col-md-3 col-6 mb-4">
        <h6 class="mb-4">Social Links</h6>
        <ul class="list-unstyled footer-list">
          <li><a [href]="author.facebook_url" *ngIf="author.facebook_url !== ''"><i class="fa-brands fa-square-facebook"></i> Facebook</a></li>
          <li><a [href]="author.twitter_handle" *ngIf="author.twitter_handle !== ''"><i class="fa-brands fa-square-x-twitter"></i> Twitter</a></li>
          <li><a [href]="author.linkedin_url" *ngIf="author.linkedin_url"><i class="fa-brands fa-linkedin"></i> Linkedin</a></li>
          <li><a href="https://github.com/vladimirandavs19"><i class="fa-brands fa-square-github"></i> Github</a></li>
        </ul>
      </div>

      <div class="col-md-3 mb-4">
        <h6 class="mb-4">Subscribe Newsletter</h6>
        <form class="subscription" action="javascript:void(0)" method="post">
          <div class="position-relative">
            <i class="ti-email email-icon"></i>
            <input
              type="email"
              class="form-control"
              placeholder="Your Email Address"
            />
          </div>
          <button class="btn btn-primary btn-block rounded" type="submit">
            Subscribe now
          </button>
        </form>
      </div>
    </div>
    <div class="row">
      <div class="col-md-12">
        <h4>Este blog ha sido realizado con la ayuda de</h4>
        <img src="https://cdn.buttercms.com/PGJPyIwaQ2KnOA8UyKfH" alt="buttercms" width="300px" />
      </div>
    </div>
    <div class="scroll-top">
      <a id="scrollTop" (click)="scrollToTop();"
        ><i class="ti-angle-up"></i
      ></a>
    </div>
    <div class="text-center">
      <p class="content">
        &copy; 2020 - Design &amp; Develop By
        <a href="https://themefisher.com/" target="_blank">Themefisher</a>
      </p>
    </div>
  </div>
</footer>