Configuración Beta de los Posts
All checks were successful
Verificar versión, Compilar y Desplegar / check-version (push) Successful in 8s
Verificar versión, Compilar y Desplegar / build (push) Successful in 1m4s
Verificar versión, Compilar y Desplegar / deploy (push) Successful in 25s

This commit is contained in:
2024-10-15 21:22:53 +02:00
parent 99bb31fd8a
commit 255e5c3307
8 changed files with 243 additions and 21 deletions

View File

@@ -6,4 +6,5 @@ import mdx from '@astrojs/mdx';
export default defineConfig({ export default defineConfig({
// Enable Svelte to support Svelte components. // Enable Svelte to support Svelte components.
integrations: [mdx()], integrations: [mdx()],
site: "https://ecobjetivos.h4ckdata.es"
}); });

View File

@@ -1,7 +1,7 @@
{ {
"name": "websostenible", "name": "websostenible",
"type": "module", "type": "module",
"version": "0.0.6", "version": "0.1.0",
"scripts": { "scripts": {
"dev": "astro dev", "dev": "astro dev",
"devhost": "astro dev --host", "devhost": "astro dev --host",

View File

View File

@@ -1,10 +1,11 @@
--- ---
import { Image } from "astro:assets"; import { Image } from "astro:assets";
const { home, posts, proyectos } = Astro.props;
--- ---
<nav class="navbar navbar-expand-lg navbar-light bg-light fixed-top"> <nav class="navbar navbar-expand-lg navbar-light bg-light fixed-top">
<div class="container"> <div class="container">
<a class="navbar-brand d-flex align-items-center" href="#"> <a class="navbar-brand d-flex align-items-center" href={home ? home : "/"}>
<Image <Image
src="/imgs/logo.png" src="/imgs/logo.png"
alt="Logo Ecobjetivos" alt="Logo Ecobjetivos"
@@ -28,11 +29,10 @@ import { Image } from "astro:assets";
<div class="collapse navbar-collapse" id="navbarNav"> <div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto"> <ul class="navbar-nav ms-auto">
<li class="nav-item"> <li class="nav-item">
<a type="button" class="nav-link btn btn-light" href="#posts">Posts</a <a type="button" class="nav-link btn btn-light" href={posts ? posts : "#posts"}>Posts</a>
>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a type="button" class="nav-link btn btn-light" href="#proyectos" <a type="button" class="nav-link btn btn-light" href={proyectos ? proyectos : "#proyectos"}
>Proyectos</a >Proyectos</a
> >
</li> </li>

View File

@@ -0,0 +1,28 @@
---
const { currentPost } = Astro.props;
// Aquí deberías implementar la lógica para obtener posts relacionados
// Por ejemplo, basándote en categorías, tags, o algún otro criterio
const relatedPosts = [{ title: "Prueba", excerpt: "Prueba", url: "Prueba" }];
---
<section class="related-posts mt-5">
<h2>Posts Relacionados</h2>
<div class="row">
{
relatedPosts.map((post) => (
<div class="col-md-4 mb-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">{post.title}</h5>
<p class="card-text">{post.excerpt}</p>
<a href={post.url} class="btn btn-primary">
Leer más
</a>
</div>
</div>
</div>
))
}
</div>
</section>

View File

@@ -1,19 +1,198 @@
--- ---
const { titulo } = Astro.props; // src/layouts/PostLayout.astro
import { getHeadings } from '../utils/getHeadings'; // Asumimos que crearemos esta utilidad
import RelatedPosts from '../components/PostsRelacionados.astro'; // Componente para posts relacionados
import Navbar from '../components/Navbar.astro';
const { frontmatter, content } = Astro.props;
const headings = getHeadings(content);
const description = frontmatter.descripcion;
// URLs para compartir en redes sociales
const shareUrl = new URL(Astro.url.pathname, Astro.site).toString();
const facebookShareUrl = `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(shareUrl)}`;
const twitterShareUrl = `https://twitter.com/intent/tweet?url=${encodeURIComponent(shareUrl)}&text=${encodeURIComponent(frontmatter.title)}`;
const linkedinShareUrl = `https://www.linkedin.com/shareArticle?mini=true&url=${encodeURIComponent(shareUrl)}&title=${encodeURIComponent(frontmatter.title)}`;
--- ---
<html lang="es"> <html lang="es">
<head> <head>
<meta charset="utf-8" /> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"> <title>{frontmatter.title} - Ecobjetivos</title>
<title>EcoFuturo</title> <meta name="description" content={description}>
<link rel="canonical" href={new URL(Astro.url.pathname, Astro.site).toString()}>
<!-- Open Graph / Facebook -->
<meta property="og:type" content="article">
<meta property="og:url" content={Astro.url}>
<meta property="og:title" content={frontmatter.title}>
<meta property="og:description" content={description}>
<meta property="og:image" content={frontmatter.image && new URL(frontmatter.image, Astro.site)}>
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image">
<meta property="twitter:url" content={Astro.url}>
<meta property="twitter:title" content={frontmatter.title}>
<meta property="twitter:description" content={description}>
<meta property="twitter:image" content={frontmatter.image && new URL(frontmatter.image, Astro.site)}>
<!-- Structured Data for Google -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "${frontmatter.titulo}",
"image": "${frontmatter.imagen && new URL(frontmatter.imagen, Astro.site)}",
"datePublished": "${frontmatter.fecha}",
"dateModified": "${frontmatter.lastModified || frontmatter.fecha}",
"author": {
"@type": "Person",
"name": "${frontmatter.autor}"
},
"publisher": {
"@type": "Organization",
"name": "Ecobjetivos",
"logo": {
"@type": "ImageObject",
"url": "${new URL('/logo.png', Astro.site)}"
}
},
"description": "${description}"
}
</script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<style>
body {
font-family: 'Arial', sans-serif;
line-height: 1.6;
color: #333;
}
.post-header {
background-color: #4CAF50;
color: white;
padding: 2rem 0;
}
.post-content {
font-size: 1.1rem;
}
.post-content img {
max-width: 100%;
height: auto;
margin: 1.5rem 0;
}
.post-meta {
font-size: 0.9rem;
color: #666;
}
blockquote {
background-color: #f9f9f9;
border-left: 5px solid #4CAF50;
padding: 1rem;
margin: 1rem 0;
font-style: italic;
}
.table-of-contents {
background-color: #f3f3f3;
padding: 1rem;
border-radius: 5px;
margin-bottom: 2rem;
}
.table-of-contents ul {
list-style-type: none;
padding-left: 0;
}
.table-of-contents ul ul {
padding-left: 1rem;
}
.table-of-contents {
background-color: #f3f3f3;
padding: 1rem;
border-radius: 5px;
margin-bottom: 2rem;
}
.table-of-contents ul {
list-style-type: none;
padding-left: 0;
}
.table-of-contents ul ul {
padding-left: 1rem;
}
.table-of-contents a {
color: #333;
text-decoration: none;
}
.table-of-contents a:hover {
color: #4CAF50;
}
</style>
</head> </head>
<body> <body>
<main> <Navbar posts="/" proyectos="/" />
<h1>{titulo}</h1>
<header class="post-header">
<div class="container">
<h1 class="display-4">{frontmatter.title}</h1>
<p class="post-meta">
<i class="fas fa-calendar-alt"></i> {new Date(frontmatter.fecha).toLocaleDateString('es-ES', {year: 'numeric', month: 'long', day: 'numeric'})}
&nbsp;|&nbsp;
<i class="fas fa-user"></i> {frontmatter.autor}
{frontmatter.lastModified && (
<>&nbsp;|&nbsp;
<i class="fas fa-edit"></i> Última actualización: {new Date(frontmatter.lastModified).toLocaleDateString('es-ES', {year: 'numeric', month: 'long', day: 'numeric'})}</>
)}
</p>
</div>
</header>
<main class="container my-5">
<div class="row">
<div class="col-lg-8">
<article class="post-content">
<slot /> <slot />
</article>
</div>
<div class="col-lg-4">
<aside class="sticky-top" style="top: 2rem;">
<div class="table-of-contents">
<h4>Contenido</h4>
<ul>
{headings.map(heading => (
<li style={`margin-left: ${(heading.depth - 1) * 1}rem`}>
<a href={`#${heading.slug}`}>{heading.text}</a>
</li>
))}
</ul>
</div>
<div class="card mb-4">
<div class="card-body">
<h5 class="card-title">Sobre el autor</h5>
<p class="card-text">{frontmatter.authorBio}</p>
</div>
</div>
<div class="card">
<div class="card-body">
<h5 class="card-title">Compartir</h5>
<a href={facebookShareUrl} target="_blank" rel="noopener noreferrer" class="btn btn-primary me-2"><i class="fab fa-facebook-f"></i></a>
<a href={twitterShareUrl} target="_blank" rel="noopener noreferrer" class="btn btn-info me-2"><i class="fab fa-twitter"></i></a>
<a href={linkedinShareUrl} target="_blank" rel="noopener noreferrer" class="btn btn-secondary"><i class="fab fa-linkedin-in"></i></a>
</div>
</div>
</aside>
</div>
</div>
<RelatedPosts currentPost={frontmatter} />
</main> </main>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
<footer class="bg-dark text-white py-4">
<!-- ... (contenido del footer) ... -->
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
</body> </body>
</html> </html>

14
src/utils/getHeadings.js Normal file
View File

@@ -0,0 +1,14 @@
export function getHeadings(content) {
const headingRegex = /^(#{1,6})\s+(.+)$/gm;
const headings = [];
let match;
while ((match = headingRegex.exec(content)) !== null) {
const depth = match[1].length;
const text = match[2];
const slug = text.toLowerCase().replace(/[^\w]+/g, '-');
headings.push({ depth, text, slug });
}
return headings;
}