Created
August 16, 2025 13:40
-
-
Save jackbaty/374d87db086babc9dc19cf856bced4cc to your computer and use it in GitHub Desktop.
Hugo New Post (bash)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Hugo new blog post script | |
| # Creates a new markdown file for blog posts | |
| # This was written entirely using Claude, if that matters to you | |
| # It mimics what I used in Emacs, and is specific to my setup | |
| # Function to convert title to slug (dashed words) | |
| title_to_slug() { | |
| echo "$1" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-\|-$//g' | |
| } | |
| # Function to prompt for yes/no | |
| ask_yes_no() { | |
| while true; do | |
| read -p "$1 (y/n): " yn | |
| case $yn in | |
| [Yy]* ) return 0;; | |
| [Nn]* ) return 1;; | |
| * ) echo "Please answer yes or no.";; | |
| esac | |
| done | |
| } | |
| # Check for help flag first | |
| if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then | |
| echo "Usage: $0 [OPTIONS] \"Post Title\"" | |
| echo " $0 [OPTIONS] (will prompt for title)" | |
| echo "" | |
| echo "Options:" | |
| echo " -f, --force Overwrite existing file" | |
| echo " -b, --bundle Create as bundle (directory with index.md)" | |
| echo " -s, --single Create as single file (.md)" | |
| echo " -h, --help Show this help message" | |
| echo "" | |
| echo "If neither -b nor -s is specified, you will be prompted to choose." | |
| exit 0 | |
| fi | |
| # Parse command line arguments | |
| FORCE_OVERWRITE=false | |
| BUNDLE_MODE="" | |
| TITLE="" | |
| while [[ $# -gt 0 ]]; do | |
| case $1 in | |
| -f|--force) | |
| FORCE_OVERWRITE=true | |
| shift | |
| ;; | |
| -b|--bundle) | |
| BUNDLE_MODE="yes" | |
| shift | |
| ;; | |
| -s|--single) | |
| BUNDLE_MODE="no" | |
| shift | |
| ;; | |
| -*) | |
| echo "Unknown option $1" | |
| exit 1 | |
| ;; | |
| *) | |
| TITLE="$1" | |
| shift | |
| ;; | |
| esac | |
| done | |
| # Get title if not provided | |
| if [ -z "$TITLE" ]; then | |
| read -p "Title: " TITLE | |
| fi | |
| # Validate title | |
| if [ -z "$TITLE" ]; then | |
| echo "Error: Title cannot be empty" | |
| exit 1 | |
| fi | |
| # Get current date components | |
| YEAR=$(date +%Y) | |
| MONTH=$(date +%m) | |
| DATE_PREFIX=$(date +%Y-%m-%d) | |
| ISO_DATE=$(date +"%Y-%m-%d %H:%M:%S %z") | |
| # Create slug from title | |
| SLUG=$(title_to_slug "$TITLE") | |
| # Construct the directory path | |
| CONTENT_DIR="./content/posts/${YEAR}/${MONTH}" | |
| # Determine if we're making a bundle or single file | |
| if [ -z "$BUNDLE_MODE" ]; then | |
| if ask_yes_no "Make Bundle?"; then | |
| BUNDLE_MODE="yes" | |
| else | |
| BUNDLE_MODE="no" | |
| fi | |
| fi | |
| # Set up file path based on bundle choice | |
| if [ "$BUNDLE_MODE" = "yes" ]; then | |
| # Bundle: create directory with index.md | |
| POST_DIR="${CONTENT_DIR}/${DATE_PREFIX}-${SLUG}" | |
| FILE_PATH="${POST_DIR}/index.md" | |
| mkdir -p "$POST_DIR" | |
| else | |
| # Single file: create .md file directly | |
| FILE_PATH="${CONTENT_DIR}/${DATE_PREFIX}-${SLUG}.md" | |
| mkdir -p "$CONTENT_DIR" | |
| fi | |
| # Check if file exists and handle force flag | |
| if [ -f "$FILE_PATH" ] && [ "$FORCE_OVERWRITE" = false ]; then | |
| echo "Post already exists: $FILE_PATH" | |
| echo "Use -f or --force flag to overwrite, or edit the existing file." | |
| exit 1 | |
| fi | |
| # Show overwrite warning if forcing | |
| if [ "$FORCE_OVERWRITE" = true ] && [ -f "$FILE_PATH" ]; then | |
| echo "Overwriting existing file: $FILE_PATH" | |
| fi | |
| # Create the markdown file with frontmatter | |
| cat > "$FILE_PATH" << EOF | |
| --- | |
| title: '${TITLE}' | |
| date: ${ISO_DATE} | |
| slug: ${SLUG} | |
| categories: [""] | |
| tags: [""] | |
| summary: | |
| draft: true | |
| cover: | |
| image: | |
| alt: | |
| caption: | |
| relative: true | |
| --- | |
| EOF | |
| echo "Created new blog post: $FILE_PATH" | |
| # Optionally open the file in your preferred editor | |
| # Uncomment one of the following lines based on your preference: | |
| # code "$FILE_PATH" # VS Code | |
| # vim "$FILE_PATH" # Vim | |
| # nano "$FILE_PATH" # Nano | |
| # open "$FILE_PATH" # macOS default app | |
| bbedit "$FILE_PATH" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment