Spaces:
Sleeping
Sleeping
| // pages/api/jekyll/create.js | |
| import { exec } from 'child_process'; | |
| import { promisify } from 'util'; | |
| import path from 'path'; | |
| import fs from 'fs-extra'; | |
| const execAsync = promisify(exec); | |
| export default async function handler(req, res) { | |
| if (req.method !== 'POST') { | |
| return res.status(405).json({ error: 'Method not allowed' }); | |
| } | |
| try { | |
| const { siteName, template = 'blog', config = {} } = req.body; | |
| if (!siteName || !/^[a-zA-Z0-9-_]+$/.test(siteName)) { | |
| return res.status(400).json({ | |
| error: 'Invalid site name. Use only alphanumeric, dash, and underscore.' | |
| }); | |
| } | |
| const sitePath = path.join('/app/projects', siteName); | |
| // Check if site already exists | |
| if (await fs.pathExists(sitePath)) { | |
| return res.status(409).json({ | |
| error: 'Site already exists' | |
| }); | |
| } | |
| // Create Jekyll site menggunakan entrypoint script | |
| console.log(`Creating Jekyll site: ${siteName}`); | |
| const { stdout, stderr } = await execAsync( | |
| `/usr/local/bin/entrypoint.sh create-site ${siteName}`, | |
| { | |
| timeout: 30000, | |
| cwd: '/app' | |
| } | |
| ); | |
| // Customize site based on template | |
| await customizeJekyllSite(sitePath, template, config); | |
| console.log('Jekyll site created:', stdout); | |
| if (stderr) console.warn('Jekyll warnings:', stderr); | |
| res.status(201).json({ | |
| success: true, | |
| message: 'Jekyll site created successfully', | |
| siteName, | |
| path: sitePath, | |
| previewUrl: `/preview/${siteName}`, | |
| output: stdout | |
| }); | |
| } catch (error) { | |
| console.error('Error creating Jekyll site:', error); | |
| res.status(500).json({ | |
| error: 'Failed to create Jekyll site', | |
| details: error.message, | |
| stderr: error.stderr || null | |
| }); | |
| } | |
| } | |
| async function customizeJekyllSite(sitePath, template, config) { | |
| try { | |
| // Update _config.yml dengan konfigurasi custom | |
| const configPath = path.join(sitePath, '_config.yml'); | |
| const defaultConfig = await fs.readFile(configPath, 'utf8'); | |
| const customConfig = `${defaultConfig} | |
| # Jekyll Studio Configuration | |
| title: ${config.title || 'My Jekyll Site'} | |
| description: ${config.description || 'Created with Jekyll Studio'} | |
| url: "" | |
| baseurl: "" | |
| # Build settings | |
| markdown: kramdown | |
| highlighter: rouge | |
| theme: minima | |
| plugins: | |
| - jekyll-feed | |
| # Exclude from processing | |
| exclude: | |
| - Gemfile | |
| - Gemfile.lock | |
| - node_modules | |
| - vendor/bundle/ | |
| - vendor/cache/ | |
| - vendor/gems/ | |
| - vendor/ruby/ | |
| `; | |
| await fs.writeFile(configPath, customConfig); | |
| // Create sample post berdasarkan template | |
| const postsDir = path.join(sitePath, '_posts'); | |
| await fs.ensureDir(postsDir); | |
| const samplePost = `--- | |
| layout: post | |
| title: "Welcome to Jekyll Studio!" | |
| date: ${new Date().toISOString().split('T')[0]} 12:00:00 +0000 | |
| categories: jekyll update | |
| --- | |
| # Welcome to Your New Jekyll Site! | |
| This site was created using **Jekyll Studio** on Hugging Face Spaces. | |
| ## Features | |
| - π Fast static site generation | |
| - π Markdown support | |
| - π¨ Customizable themes | |
| - π± Mobile responsive | |
| - π SEO optimized | |
| ## Getting Started | |
| Edit this post in \`_posts/\` directory or create new posts using the Jekyll Studio interface. | |
| Happy blogging! β¨ | |
| `; | |
| const postPath = path.join(postsDir, `${new Date().toISOString().split('T')[0]}-welcome-to-jekyll-studio.md`); | |
| await fs.writeFile(postPath, samplePost); | |
| console.log(`Jekyll site customized with ${template} template`); | |
| } catch (error) { | |
| console.warn('Failed to customize Jekyll site:', error.message); | |
| } | |
| } |