Skip to content

Instantly share code, notes, and snippets.

@RaimonxDev
Last active February 19, 2021 21:31
Show Gist options
  • Save RaimonxDev/6856a44811c730a32c897f1ecf2c433d to your computer and use it in GitHub Desktop.
Save RaimonxDev/6856a44811c730a32c897f1ecf2c433d to your computer and use it in GitHub Desktop.
Seo Services example
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Meta, MetaDefinition, Title } from '@angular/platform-browser';
import { of, Subscription } from 'rxjs';
import { catchError, map, pluck, take } from 'rxjs/operators';
import { environment } from 'src/environments/environment';
// utils
import { handleHttpResponseError } from '@utils/http-errors';
// Models
import { PostResponse } from 'src/app/page-blog/models/PostResponse';
import { MetaTagsPageResponse, TAGS } from "../../models/MetaTagsPages";
@Injectable({
providedIn: 'root'
})
export interface PostResponse {
id: number;
author: Author;
published_at: Date;
created_at: Date;
updated_at: Date;
title: string;
content: string;
excerpt: string;
slug: string;
Seo: SEO[];
image: Image;
categories: Category[];
}
export interface SEO {
id: number;
name: string;
content: string;
}
export interface Author {
id: number;
first_name: string;
last_name: string;
email: string;
about_author: string;
published_at: Date;
created_at: Date;
updated_at: Date;
developer_profile: string;
social: Social[];
picture_author: Image;
}
export interface Image {
id: number;
name: string;
alternativeText: string;
caption: string;
width: number;
height: number;
formats: Formats;
hash: string;
ext: string;
mime: string;
size: number;
url: string;
previewUrl: null;
provider: string;
provider_metadata: null;
created_at: Date;
updated_at: Date;
}
export interface Formats {
small: Large;
medium: Large;
thumbnail: Large;
large?: Large;
}
export interface Large {
ext: string;
url: string;
hash: string;
mime: string;
name: string;
path: null;
size: number;
width: number;
height: number;
}
export interface Social {
id: number;
social_network: string;
link_social_network: string;
name_social_network: null;
name: string;
link: string;
}
export interface Category {
id: number;
name_category: string;
published_at: Date;
created_at: Date;
updated_at: Date;
export class SeoService {
private urlWebsite:string = environment.urlWebsite
constructor( private metaTagService: Meta,
private titleTag: Title,
private _http: HttpClient ) { }
essentialTags(): MetaDefinition[] {
// tag to facebook
const fbTitle = { 'property': 'og:title' },
fbDescription = { 'property': 'og:description' },
fbSiteName = { 'property': 'og:site_name' },
fbImage = {'property': 'og:image' },
fbUrl = { 'property': 'og:url' },
// tag to twitter
twTitle = { 'name': 'twitter:title' },
twDescription = { 'name': 'twitter:description' },
twImage = {'name': 'twitter:image' },
twUrl = {'name': 'twitter:card' };
return [fbSiteName,fbTitle,fbDescription,fbImage,fbUrl,twTitle,twDescription,twImage,twUrl]
}
formatTags(title: string , description: string , image : string = '/uploads/Plaza_Frontend_Logo_65906ca292.svg', url: string= '' ): MetaDefinition[] {
const fbTitle = {'property': 'og:title', content:title},
fbDescription = {'property': 'og:description', content:description},
fbSiteName = {'property': 'og:site_name', content:environment.nameWeb},
fbImage = {'property': 'og:image', content:`${environment.urlWebsite}${image}`},
fbUrl = {'property': 'og:url', content:`${environment.urlWebsite}${url}`},
// tag to twitter
twTitle = {'name': 'twitter:title', content:title},
twDescription = {'name': 'twitter:description', content:description},
twImage = {'name': 'twitter:image', content:`${environment.urlWebsite}${image}`},
twUrl = {'name': 'twitter:card', content:`${environment.urlWebsite}${url}`}
return [fbTitle,fbDescription,fbImage,fbUrl,twTitle,twDescription,twImage,twUrl,fbSiteName]
}
// Los tags para Post y paginas son distintos
// En Post Preparamos los tags segun el contenido del articulo
getTagsForPost(data: PostResponse){
of(data).pipe(
map( (tags: PostResponse) => {
// actualizamos el title de la pagina con el titulo del post
this.titleTag.setTitle(tags.title)
return this.formatTags(tags.title,tags.excerpt,tags.image.url,tags.slug)
}),
take(1)
)
.subscribe((tag: MetaDefinition[]) => tag.forEach(tag => this.metaTagService.updateTag(tag)))
}
// ··········································································································································
// En las paginas los Datos del "Seo" los agregamos desde el backend
getTagForPage(page: string): Subscription {
return this._http.get(`${this.urlWebsite}/${page}`)
.pipe(
catchError(handleHttpResponseError),
pluck <MetaTagsPageResponse, TAGS>('SEO'),
map<TAGS, MetaDefinition[]>( tags => {
this.titleTag.setTitle(tags.title)
return this.formatTags(tags.title, tags.description, tags.image[0].url)
}),
take(1)
)
.subscribe((tags) => tags.forEach( tag => this.metaTagService.updateTag(tag)))
}
deleteMetaTags(): Subscription{
return of(...this.essentialTags())
.pipe(
map(tagsProperty => {
const tags = []
Object.getOwnPropertyNames(tagsProperty).forEach(val => {
tags.push(`${val}='${tagsProperty[val]}'`);
});
return tags
})
).subscribe(tag => this.metaTagService.removeTag(tag[0]) )
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment