Skip to content

Instantly share code, notes, and snippets.

@fgrweb
Created November 10, 2025 11:38
Show Gist options
  • Select an option

  • Save fgrweb/6d007a3220c22cdf3df26fee651e4fb7 to your computer and use it in GitHub Desktop.

Select an option

Save fgrweb/6d007a3220c22cdf3df26fee651e4fb7 to your computer and use it in GitHub Desktop.
Script to customise the WordPress plugin boilerplate
#!/bin/bash
# Script para personalizar el boilerplate de plugin de WordPress
# Autor: F.GR Web
# Versión: 1.0.0
set -e
# Colores para output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Variables
BOILERPLATE_REPO="https://github.com/fgrweb/fgrweb-plugin.git"
TEMP_DIR=".boilerplate-temp"
# Función para imprimir mensajes con color
print_message() {
echo -e "${2}${1}${NC}"
}
print_success() {
print_message "✓ $1" "$GREEN"
}
print_error() {
print_message "✗ $1" "$RED"
}
print_info() {
print_message "ℹ $1" "$BLUE"
}
print_warning() {
print_message "⚠ $1" "$YELLOW"
}
# Función para limpiar en caso de error
cleanup() {
if [ -d "$TEMP_DIR" ]; then
rm -rf "$TEMP_DIR"
fi
}
trap cleanup EXIT
# Función para convertir slug a formato de clase (con guiones bajos y primera letra mayúscula)
slug_to_class() {
echo "$1" | sed 's/-/_/g' | awk '{for(i=1;i<=NF;i++){split($i,a,"_"); for(j in a){a[j]=toupper(substr(a[j],1,1)) substr(a[j],2)}} print a[1]"_"a[2]"_"a[3]"_"a[4]"_"a[5]}' | sed 's/_*$//'
}
# Función para convertir slug a formato de constante (mayúsculas con guiones bajos)
slug_to_const() {
echo "$1" | tr '[:lower:]' '[:upper:]' | tr '-' '_'
}
# Función para convertir slug a formato de función (minúsculas con guiones bajos)
slug_to_function() {
echo "$1" | tr '-' '_'
}
# Banner
clear
print_info "================================================"
print_info " WordPress Plugin Boilerplate Setup Script"
print_info "================================================"
echo ""
# Verificar que el directorio esté vacío (excepto este script)
FILE_COUNT=$(ls -A | grep -v "setup-plugin.sh" | wc -l)
if [ $FILE_COUNT -gt 0 ]; then
print_error "Este directorio no está vacío. El script debe ejecutarse en un directorio vacío."
exit 1
fi
# 1. Descargar archivos del repositorio remoto
print_info "Paso 1: Descargando archivos del boilerplate..."
echo ""
print_info "Clonando repositorio desde: $BOILERPLATE_REPO"
git clone --depth 1 "$BOILERPLATE_REPO" "$TEMP_DIR" 2>/dev/null
if [ ! -d "$TEMP_DIR" ]; then
print_error "Error al clonar el repositorio"
exit 1
fi
# Mover archivos del temporal al directorio actual
print_info "Copiando archivos..."
mv "$TEMP_DIR"/* .
mv "$TEMP_DIR"/.* . 2>/dev/null || true
# Limpiar directorio temporal
rm -rf "$TEMP_DIR"
# Eliminar la referencia al repositorio original
rm -rf .git
print_success "Archivos descargados correctamente"
echo ""
# 2. Solicitar datos al usuario
print_info "Paso 2: Configuración del plugin"
echo ""
# Slug del plugin
while true; do
read -p "$(echo -e ${BLUE}Introduce el slug del plugin \(ej: mi-plugin-increible\): ${NC})" NEW_SLUG
if [[ -z "$NEW_SLUG" ]]; then
print_error "El slug no puede estar vacío"
elif [[ ! "$NEW_SLUG" =~ ^[a-z0-9-]+$ ]]; then
print_error "El slug solo puede contener letras minúsculas, números y guiones"
else
break
fi
done
# Text domain
read -p "$(echo -e ${BLUE}Introduce el text domain \(presiona Enter para usar \"$NEW_SLUG\"\): ${NC})" TEXT_DOMAIN
if [[ -z "$TEXT_DOMAIN" ]]; then
TEXT_DOMAIN="$NEW_SLUG"
fi
# Nombre del plugin
read -p "$(echo -e ${BLUE}Introduce el nombre del plugin: ${NC})" PLUGIN_NAME
while [[ -z "$PLUGIN_NAME" ]]; do
print_error "El nombre del plugin no puede estar vacío"
read -p "$(echo -e ${BLUE}Introduce el nombre del plugin: ${NC})" PLUGIN_NAME
done
# Plugin URI
read -p "$(echo -e ${BLUE}Introduce la URI del plugin: ${NC})" PLUGIN_URI
if [[ -z "$PLUGIN_URI" ]]; then
PLUGIN_URI="https://fgrweb.es"
fi
# Descripción
read -p "$(echo -e ${BLUE}Introduce la descripción del plugin: ${NC})" PLUGIN_DESCRIPTION
if [[ -z "$PLUGIN_DESCRIPTION" ]]; then
PLUGIN_DESCRIPTION="Custom plugin"
fi
# Autor
read -p "$(echo -e ${BLUE}Introduce el nombre del autor: ${NC})" AUTHOR_NAME
if [[ -z "$AUTHOR_NAME" ]]; then
AUTHOR_NAME="Fernando García Rebolledo"
fi
# Autor URI
read -p "$(echo -e ${BLUE}Introduce la URI del autor: ${NC})" AUTHOR_URI
if [[ -z "$AUTHOR_URI" ]]; then
AUTHOR_URI="https://fgrweb.es"
fi
# Confirmación
echo ""
print_info "================================================"
print_info "Resumen de la configuración:"
print_info "================================================"
echo "Slug: $NEW_SLUG"
echo "Text Domain: $TEXT_DOMAIN"
echo "Nombre: $PLUGIN_NAME"
echo "Plugin URI: $PLUGIN_URI"
echo "Descripción: $PLUGIN_DESCRIPTION"
echo "Autor: $AUTHOR_NAME"
echo "Autor URI: $AUTHOR_URI"
print_info "================================================"
echo ""
read -p "$(echo -e ${YELLOW}¿Continuar con estos datos? \(s/n\): ${NC})" CONFIRM
if [[ ! "$CONFIRM" =~ ^[sS]$ ]]; then
print_warning "Operación cancelada"
exit 0
fi
echo ""
print_info "Paso 3: Aplicando transformaciones..."
echo ""
# Calcular diferentes formatos del slug
OLD_SLUG="fgrweb-plugin"
OLD_CLASS="Fgrweb_Plugin"
OLD_CONST="FGRWEB_PLUGIN"
OLD_FUNCTION="fgrweb_plugin"
OLD_OPTION="fgrweb_plugin"
NEW_CLASS=$(slug_to_class "$NEW_SLUG")
NEW_CONST=$(slug_to_const "$NEW_SLUG")
NEW_FUNCTION=$(slug_to_function "$NEW_SLUG")
NEW_OPTION=$(slug_to_function "$NEW_SLUG")
print_info "Formatos generados:"
echo " Clase: $NEW_CLASS"
echo " Constante: $NEW_CONST"
echo " Función: $NEW_FUNCTION"
echo ""
# 3. Reemplazar contenido en archivos
print_info "Actualizando contenido de archivos..."
# Buscar todos los archivos PHP, CSS, JS, y TXT
FILES=$(find . -type f \( -name "*.php" -o -name "*.css" -o -name "*.js" -o -name "*.txt" -o -name "*.pot" \) ! -path "*/\.*" ! -path "*/node_modules/*" ! -path "*/vendor/*" ! -name "setup-plugin.sh")
for file in $FILES; do
if [ -f "$file" ]; then
# Reemplazar nombres de clases
sed -i '' "s/${OLD_CLASS}_/${NEW_CLASS}_/g" "$file"
sed -i '' "s/${OLD_CLASS}/${NEW_CLASS}/g" "$file"
# Reemplazar constantes
sed -i '' "s/${OLD_CONST}_/${NEW_CONST}_/g" "$file"
sed -i '' "s/${OLD_CONST}/${NEW_CONST}/g" "$file"
# Reemplazar funciones
sed -i '' "s/${OLD_FUNCTION}_/${NEW_FUNCTION}_/g" "$file"
sed -i '' "s/${OLD_FUNCTION}/${NEW_FUNCTION}/g" "$file"
# Reemplazar opciones y slugs
sed -i '' "s/${OLD_OPTION}_/${NEW_OPTION}_/g" "$file"
sed -i '' "s/${OLD_OPTION}/${NEW_OPTION}/g" "$file"
# Reemplazar slug en rutas y nombres
sed -i '' "s/${OLD_SLUG}/${NEW_SLUG}/g" "$file"
# Reemplazar text domain
sed -i '' "s/'fgrweb-plugin'/'${TEXT_DOMAIN}'/g" "$file"
sed -i '' "s/\"fgrweb-plugin\"/\"${TEXT_DOMAIN}\"/g" "$file"
# Actualizar @package
sed -i '' "s/@package Fgrweb_Plugin/@package ${NEW_CLASS}/g" "$file"
sed -i '' "s/@subpackage Fgrweb_Plugin/@subpackage ${NEW_CLASS}/g" "$file"
fi
done
print_success "Contenido actualizado en todos los archivos"
# 4. Actualizar cabecera del plugin principal
print_info "Actualizando cabecera del plugin..."
MAIN_FILE="${OLD_SLUG}.php"
if [ -f "$MAIN_FILE" ]; then
# Actualizar Plugin Name
sed -i '' "s/Plugin Name:.*/Plugin Name: ${PLUGIN_NAME}/g" "$MAIN_FILE"
# Actualizar Plugin URI
sed -i '' "s|Plugin URI:.*|Plugin URI: ${PLUGIN_URI}|g" "$MAIN_FILE"
# Actualizar Description
sed -i '' "s/Description:.*/Description: ${PLUGIN_DESCRIPTION}/g" "$MAIN_FILE"
# Actualizar Author
sed -i '' "s/Author:.*/Author: ${AUTHOR_NAME}/g" "$MAIN_FILE"
# Actualizar Author URI
sed -i '' "s|Author URI:.*|Author URI: ${AUTHOR_URI}/|g" "$MAIN_FILE"
# Actualizar @link en los archivos PHP
for file in $FILES; do
if [[ "$file" == *.php ]]; then
sed -i '' "s|@link.*https://fgrweb.es|@link ${PLUGIN_URI}|g" "$file"
fi
done
print_success "Cabecera actualizada"
else
print_warning "Archivo principal no encontrado: $MAIN_FILE"
fi
# 5. Renombrar archivos
print_info "Renombrando archivos..."
# Encontrar todos los archivos que contienen el slug antiguo
FILES_TO_RENAME=$(find . -type f -name "*${OLD_SLUG}*" ! -path "*/\.*" ! -path "*/node_modules/*" ! -path "*/vendor/*" ! -name "setup-plugin.sh")
for old_file in $FILES_TO_RENAME; do
new_file=$(echo "$old_file" | sed "s/${OLD_SLUG}/${NEW_SLUG}/g")
if [ "$old_file" != "$new_file" ]; then
# Crear directorio si no existe
mkdir -p "$(dirname "$new_file")"
mv "$old_file" "$new_file"
print_success "Renombrado: $(basename "$old_file") → $(basename "$new_file")"
fi
done
# 6. Renombrar directorios si es necesario
DIRS_TO_RENAME=$(find . -type d -name "*${OLD_SLUG}*" ! -path "*/\.*" ! -path "*/node_modules/*" ! -path "*/vendor/*" | sort -r)
for old_dir in $DIRS_TO_RENAME; do
new_dir=$(echo "$old_dir" | sed "s/${OLD_SLUG}/${NEW_SLUG}/g")
if [ "$old_dir" != "$new_dir" ] && [ -d "$old_dir" ]; then
mv "$old_dir" "$new_dir"
print_success "Directorio renombrado: $(basename "$old_dir") → $(basename "$new_dir")"
fi
done
echo ""
print_success "Plugin personalizado correctamente"
# 7. Crear archivo .gitignore
echo ""
print_info "Creando archivo .gitignore..."
cat > .gitignore << 'EOF'
# Setup script
setup-plugin.sh
# Logs and databases
*.log
*.sql
*.sqlite
# Environment files with sensitive information
.env
.env.*
# Development tools
/node_modules/
/vendor/
npm-debug.log
yarn-error.log
/dist/
/build/
package-lock.json
composer.lock
# System files
.DS_Store
Thumbs.db
*.swp
*.swo
# IDE and editor folders
/.idea/
/.vscode/*
!/.vscode/settings.json
!/.vscode/tasks.json
!/.vscode/launch.json
!/.vscode/extensions.json
# Local by Flywheel specific
/local-site.json
/local-xdebuginfo.php
# Client-specific override files
.client-overrides.json
# Deployment exclusions
.deployignore
# Temporary files
*.tmp
*.bak
*.swp
*.zip
EOF
print_success ".gitignore creado correctamente"
# 8. Preguntar si quiere añadir a repositorio remoto
echo ""
read -p "$(echo -e ${BLUE}¿Deseas subir este plugin a un repositorio remoto? \(s/n\): ${NC})" ADD_REMOTE
if [[ "$ADD_REMOTE" =~ ^[sS]$ ]]; then
echo ""
read -p "$(echo -e ${BLUE}Introduce la URL del repositorio remoto: ${NC})" REMOTE_URL
if [[ -z "$REMOTE_URL" ]]; then
print_warning "URL vacía. No se configurará repositorio remoto."
else
print_info "Inicializando repositorio Git..."
git init
print_info "Configurando repositorio remoto..."
git remote add origin "$REMOTE_URL"
print_info "Añadiendo archivos..."
git add .
print_info "Creando commit inicial..."
git commit -m "Initial commit"
print_info "Creando rama main..."
git branch -M main
print_info "Subiendo archivos al repositorio remoto..."
if git push -u origin main; then
print_success "Plugin subido correctamente a: $REMOTE_URL"
else
print_error "Error al subir al repositorio remoto"
print_warning "Puedes intentar subirlo manualmente con: git push -u origin main"
fi
fi
else
print_info "Plugin no subido a repositorio remoto"
print_info "Si deseas crear un repositorio local, ejecuta: git init"
fi
# 9. Limpiar el script de setup
echo ""
print_info "Limpiando archivos temporales..."
# Eliminar este script
rm -f setup-plugin.sh
print_success "Setup completado"
# 10. Resumen final
echo ""
print_info "================================================"
print_success "¡Plugin personalizado exitosamente!"
print_info "================================================"
echo ""
print_info "Próximos pasos:"
echo " 1. Revisa los archivos generados"
echo " 2. Instala el plugin en WordPress"
echo " 3. Comienza a desarrollar tu funcionalidad"
echo ""
print_info "Archivo principal del plugin: ${NEW_SLUG}.php"
print_info "================================================"
echo ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment