// ==================== // // Blog Data // ==================== // const blogPosts = [ { id: 1, title: "Introducción a JavaScript Moderno: ES6 y más allá", excerpt: "Descubre las características más importantes de JavaScript moderno, desde arrow functions hasta async/await, y cómo pueden mejorar tu código.", date: "2024-12-10", tags: ["javascript", "web"], image: null, content: `

¿Qué es ES6?

ECMAScript 6 (ES6), también conocido como ECMAScript 2015, fue un gran salto en la evolución de JavaScript. Introdujo características que hacen el código más limpio, legible y mantenible.

Arrow Functions

Las arrow functions proporcionan una sintaxis más concisa para escribir funciones:

// Función tradicional
function suma(a, b) {
    return a + b;
}

// Arrow function
const suma = (a, b) => a + b;

Template Literals

Permiten crear strings de manera más flexible:

const nombre = "RuVaz";
const saludo = \`Hola, \${nombre}! Bienvenido al blog.\`;

Destructuring

Facilita la extracción de valores de arrays y objetos:

const usuario = { nombre: "RuVaz", edad: 25 };
const { nombre, edad } = usuario;

Async/Await

Simplifica el trabajo con código asíncrono:

async function obtenerDatos() {
    try {
        const response = await fetch('https://api.ejemplo.com/datos');
        const data = await response.json();
        return data;
    } catch (error) {
        console.error('Error:', error);
    }
}

Conclusión

JavaScript moderno ofrece herramientas poderosas que mejoran significativamente la experiencia de desarrollo. Estas características no solo hacen el código más elegante, sino también más fácil de mantener y debuggear.

` }, { id: 2, title: "Python para Data Science: Primeros Pasos", excerpt: "Una guía práctica para comenzar con Python en el mundo del análisis de datos, incluyendo pandas, numpy y visualización.", date: "2024-12-08", tags: ["python"], image: null, content: `

¿Por qué Python para Data Science?

Python se ha convertido en el lenguaje preferido para ciencia de datos gracias a su simplicidad y el ecosistema de bibliotecas especializadas.

Bibliotecas Esenciales

Ejemplo con Pandas

import pandas as pd

# Crear un DataFrame
datos = {
    'nombre': ['Ana', 'Luis', 'María'],
    'edad': [25, 30, 28],
    'ciudad': ['Madrid', 'Barcelona', 'Valencia']
}

df = pd.DataFrame(datos)
print(df.head())

Visualización Básica

import matplotlib.pyplot as plt

# Crear un gráfico simple
edades = [25, 30, 28, 35, 40]
plt.plot(edades)
plt.title('Distribución de Edades')
plt.xlabel('Índice')
plt.ylabel('Edad')
plt.show()

Próximos Pasos

Una vez domines estas herramientas básicas, podrás explorar análisis más avanzados, machine learning y visualizaciones interactivas con bibliotecas como Plotly.

` }, { id: 3, title: "Desarrollo Web Responsivo: Guía Completa", excerpt: "Aprende las mejores prácticas para crear sitios web que se vean perfectos en cualquier dispositivo, desde móviles hasta pantallas grandes.", date: "2024-12-05", tags: ["web", "javascript"], image: null, content: `

¿Qué es el Diseño Responsivo?

El diseño responsivo es una técnica de desarrollo web que permite que los sitios se adapten automáticamente a diferentes tamaños de pantalla y dispositivos.

Mobile-First Approach

Comenzar diseñando para móviles y luego expandir a pantallas más grandes:

/* Estilos base para móvil */
.container {
    width: 100%;
    padding: 1rem;
}

/* Tablet */
@media (min-width: 768px) {
    .container {
        max-width: 720px;
        margin: 0 auto;
    }
}

/* Desktop */
@media (min-width: 1024px) {
    .container {
        max-width: 960px;
    }
}

CSS Grid y Flexbox

Herramientas modernas para layouts responsivos:

/* Grid responsivo */
.grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 1rem;
}

/* Flexbox */
.flex-container {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
}

Imágenes Responsivas

<img 
    src="proxy.php?url=https%3A%2F%2Fruvaz.github.io%2Fimagen-small.jpg"
    srcset="imagen-small.jpg 480w,
            imagen-medium.jpg 768w,
            imagen-large.jpg 1200w"
    sizes="(max-width: 768px) 100vw, 50vw"
    alt="Descripción"
/>

Mejores Prácticas

` }, { id: 4, title: "Git y GitHub: Control de Versiones Esencial", excerpt: "Domina Git y GitHub para gestionar tus proyectos de manera profesional y colaborar eficientemente con otros desarrolladores.", date: "2024-12-01", tags: ["devops"], image: null, content: `

¿Por qué usar Git?

Git es el sistema de control de versiones más popular, permitiéndote rastrear cambios, colaborar con otros y mantener un historial completo de tu proyecto.

Comandos Básicos

# Inicializar un repositorio
git init

# Añadir archivos al staging
git add .

# Crear un commit
git commit -m "Descripción del cambio"

# Ver el estado
git status

# Ver el historial
git log --oneline

Trabajando con Ramas

# Crear una nueva rama
git branch feature-nueva

# Cambiar a la rama
git checkout feature-nueva

# O crear y cambiar en un solo comando
git checkout -b feature-nueva

# Fusionar ramas
git checkout main
git merge feature-nueva

GitHub Workflow

# Clonar un repositorio
git clone https://github.com/usuario/repo.git

# Añadir un remoto
git remote add origin https://github.com/usuario/repo.git

# Subir cambios
git push origin main

# Obtener cambios
git pull origin main

Mejores Prácticas

GitHub Pages

GitHub Pages te permite alojar sitios web estáticos directamente desde tu repositorio, ¡como este blog!

` } ]; // ==================== // // DOM Elements // ==================== // const blogGrid = document.getElementById('blog-grid'); const filterTags = document.querySelectorAll('.tag'); const articleCount = document.getElementById('article-count'); // ==================== // // Functions // ==================== // // Render blog posts function renderBlogPosts(posts) { blogGrid.innerHTML = ''; posts.forEach(post => { const card = createBlogCard(post); blogGrid.appendChild(card); }); // Update article count with animation animateCounter(articleCount, posts.length); } // Create blog card element function createBlogCard(post) { const card = document.createElement('article'); card.className = 'blog-card'; card.dataset.tags = post.tags.join(','); const imageHtml = post.image ? `${post.title}` : '
'; const tagsHtml = post.tags .map(tag => `${tag}`) .join(''); card.innerHTML = ` ${imageHtml}
${tagsHtml} ${formatDate(post.date)}

${post.title}

${post.excerpt}

Leer más
`; return card; } // Format date function formatDate(dateString) { const options = { year: 'numeric', month: 'long', day: 'numeric' }; const date = new Date(dateString); return date.toLocaleDateString('es-ES', options); } // Animate counter function animateCounter(element, target) { let current = 0; const increment = target / 30; const timer = setInterval(() => { current += increment; if (current >= target) { element.textContent = target; clearInterval(timer); } else { element.textContent = Math.floor(current); } }, 30); } // Filter posts by tag function filterPosts(filterTag) { const cards = document.querySelectorAll('.blog-card'); cards.forEach(card => { const cardTags = card.dataset.tags.split(','); if (filterTag === 'all' || cardTags.includes(filterTag)) { card.style.display = 'block'; card.style.animation = 'fadeInUp 0.6s ease forwards'; } else { card.style.display = 'none'; } }); } // ==================== // // Event Listeners // ==================== // // Filter tags click filterTags.forEach(tag => { tag.addEventListener('click', () => { // Remove active class from all tags filterTags.forEach(t => t.classList.remove('active')); // Add active class to clicked tag tag.classList.add('active'); // Filter posts const filter = tag.dataset.filter; filterPosts(filter); }); }); // Smooth scroll for navigation links document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); const target = document.querySelector(this.getAttribute('href')); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }); }); // Header scroll effect let lastScroll = 0; const header = document.querySelector('.header'); window.addEventListener('scroll', () => { const currentScroll = window.pageYOffset; if (currentScroll > 100) { header.style.boxShadow = '0 4px 20px rgba(0, 0, 0, 0.3)'; } else { header.style.boxShadow = 'none'; } lastScroll = currentScroll; }); // ==================== // // Initialize // ==================== // document.addEventListener('DOMContentLoaded', () => { renderBlogPosts(blogPosts); }); // ==================== // // Export for article page // ==================== // if (typeof window !== 'undefined') { window.blogPosts = blogPosts; }