Skip to content

ETVO/etvo-manage

Repository files navigation

📝 ETVO Manage - Lightweight Headless CMS

A lightweight, headless content management system built from scratch with PHP and JSON files, designed to fit comfortably within 1GB hosting limits while delivering an intuitive block-based editing experience.

Note: This project is no longer actively maintained. Frontend implementations include etvo-page and velvetcare, though versions may be incompatible as these projects are also unmaintained.

🎯 Overview

Zero-dependency PHP CMS that runs on minimal infrastructure without external libraries. ETVO Manage provides a dynamic block-based content editor with a flexible JSON-driven architecture. Unlike traditional headless CMSs with REST APIs, ETVO Manage uses direct file inclusion for ultra-fast content delivery - the frontend simply includes CMS files to read JSON content, eliminating HTTP overhead entirely.

Built as a personal challenge to create a fully functional, production-ready CMS without relying on frameworks or libraries, proving that powerful tools can be lightweight and efficient.

✨ Key Features

  • Block-Based Content Editor - Intuitive editing experience using content blocks (text, images, galleries, videos, embeds, etc.)
  • JSON-Driven Architecture - System model, blocks, and field types configured entirely through JSON files
  • Direct File Integration - Frontend includes CMS files for zero-latency content access
  • Ultra-Lightweight - Entire CMS + content + media fits within 1GB hosting space
  • Zero Dependencies - No frameworks, no libraries - pure PHP from scratch
  • File-Based Storage - No database required - content stored in JSON files for portability
  • Dynamic Block System - Create and configure new block types without touching code
  • Flexible Field Types - Text, textarea, rich text, image, gallery, select, checkbox, date, and more

🎨 The Block Editing Experience

The heart of ETVO Manage is its block-based editor, designed with a specific philosophy in mind:

Content vs Structure

What's Flexible (No Code Required):

  • Block content (text, images, links, descriptions)
  • Number of nested items (add/remove testimonials, benefits, FAQ items)
  • Media files and their properties
  • Page-specific settings and metadata

What's Fixed (Requires Code):

  • Page structure (which blocks appear and in what order)
  • Block types available
  • Field structure within blocks
  • Layout and templates

Design Philosophy

ETVO Manage deliberately trades infinite flexibility for speed and simplicity. Rather than allowing users to add/remove/rearrange any block on any page:

  • Pages have predefined structures - The homepage has hero → services → contact → portfolio
  • Content editors focus on content - Change the hero title, update testimonials, swap images
  • Developers control structure - Adding a new block type or changing page layout requires code changes

Why This Approach?

  1. Faster Performance - No drag-and-drop overhead, no complex page builders
  2. Cleaner Code - Predictable structure makes templates simpler and more maintainable
  3. Better UX - Content editors aren't overwhelmed with layout choices
  4. Smaller Footprint - No need for complex page builder logic
  5. Focused Editing - Users concentrate on content quality, not page design

This makes ETVO Manage ideal for sites where the structure is well-defined and content updates are frequent - exactly what most institutional websites, portfolios, and small business sites need.

Intuitive Editing

Within this structure, the editor provides:

  • Simple Forms - Edit block content through straightforward input fields
  • Nested Items - Add/remove testimonials, benefits, team members with ease
  • Media Management - Upload and organize images efficiently
  • Preview - See changes before publishing

Available Block Types

Based on the implementation, blocks include:

  • Hero Block - Full-width hero sections with heading, subheading, image, and call-to-action
  • Benefits Block - Showcase features/benefits with nested benefit items, each with image, title, and description
  • Testimonials Block - Client testimonials with nested testimonial items
  • Contact Block - Contact sections with icons/links for different contact methods
  • FAQ Block - Frequently asked questions with expandable items and optional CTA
  • CTA Block - Call-to-action sections with title and button
  • Services Block - Service listings with icons and descriptions
  • Portfolio Block - Project showcase blocks
  • Custom Blocks - Define your own via JSON configuration in /admin/model/blocks/

Each block type supports nested repeatable items (like multiple benefits, testimonials, or FAQ items), allowing flexibility within the defined structure.

Block Field Types

Simple Fields:

  • string / text - Single-line text
  • textarea - Multi-line text
  • rich - WYSIWYG editor
  • number - Numeric input
  • select - Dropdown
  • image - Upload or URL (5MB limit)
  • password - Password field
  • hidden - Hidden value

Composite Fields:

  • block - Single embedded block
  • blocks - Multiple repeatable blocks with add/remove/reorder controls

Example Block Definition:

{
  "title": "Hero",
  "icon": "easel",
  "attributes": {
    "h1": {"label": "Tagline", "type": "string"},
    "image": {"label": "Image", "type": "image"},
    "action": {"label": "CTA", "type": "block", "block_id": "button"}
  }
}

🔧 JSON-Driven Configuration

The entire system architecture is configured through JSON files stored in the CMS:

/admin/model/
  ├── blocks/              # Block type definitions
  │   ├── hero.json
  │   ├── text.json
  │   └── gallery.json
  └── content-types.json   # Content structure definitions

/admin/system/
  └── settings.json        # System configuration

This approach means:

  • No code changes needed to add new block types
  • Easy customization for different project needs
  • Version control friendly - track changes to content model
  • Quick deployment - just update JSON files

🔧 Integration Architecture

ETVO Manage uses a direct file inclusion approach rather than a traditional REST API. The frontend includes CMS files to access content stored in JSON files, making it extremely lightweight with zero HTTP overhead for content delivery.

How It Works

The frontend (e.g., github.com/ETVO/etvo-page) integrates with the CMS through simple PHP includes:

// integrate.php (in frontend)
include_once './etvo-manage/const.php';
include_once CONTROL_DIR . '/util.php';

The CMS provides utility functions to read content:

// Get content data
$page_data = get_data('homepage');

// Get block model definition
$hero_model = get_block_model('hero');

// Get system settings
$settings = get_system_data('settings');

Content Storage Structure

/data/                    # Content as JSON files
  ├── content.json        # Main page content
  ├── projects.json       # Projects listing
  └── projects/
      └── project_1.json  # Individual project

/admin/model/             # Block definitions
  └── blocks/
      ├── hero.json
      ├── benefits.json
      └── testimonials.json

/admin/system/            # System configuration
  └── settings.json

Utility Functions

Core functions in util.php:

  • get_data($name) - Read content from /data/{name}.json
  • get_model($name) - Read model from /admin/model/{name}.json
  • get_block_model($id) - Read block model from /admin/model/blocks/{id}.json
  • get_system_data($name) - Read system config from /admin/system/{name}.json
  • filter_blocks($blocks) - Remove index suffixes from block keys

What filter_blocks() does:

  • Input: {"hero:0": {...}, "benefits:0": {...}}
  • Output: {"hero": {...}, "benefits": {...}}
  • Allows templates to use simple keys: $blocks['hero'] instead of $blocks['hero:0']

Example Content Structure

A page JSON file (/data/content.json) looks like this:

{
  "page_title": "ETVO - Web Design & Development",
  "blocks": {
    "hero:0": {
      "h1": "Institutional Websites Development",
      "h2": "Unlock the power of websites that work for you.",
      "image": "http://etvo-web.test/assets/img/hero.webp",
      "action": {
        "text": "Get Started",
        "link": "#benefits"
      }
    },
    "testimonials:1": {
      "title": "Client Testimonials",
      "testimonials": {
        "testimonial:0": {
          "text": "ETVO delivered exceptional results...",
          "author": "John Doe, Company"
        },
        "testimonial:1": {
          "text": "Professional and reliable service...",
          "author": "Jane Smith, Business"
        }
      }
    },
    "contact:2": {
      "title": "Connect With Us",
      "desc": "Ready to start your project?",
      "icons": {
        "icon:0": {
          "title": "WhatsApp",
          "icon": "whatsapp",
          "link": "https://wa.me/?phone=123456"
        }
      }
    }
  }
}

Block key format: blocktype:index (e.g., hero:0, testimonials:0). Blocks can contain nested structures with their own indexed items.

Frontend Rendering Example

Here's how the frontend integrates with the CMS:

<?php
// index.php
include_once 'integrate.php';

// Get page content
$content = get_data('content');
$blocks = filter_blocks($content['blocks']);
?>

<?php
// Include partial templates for each block
include './partials/header.php';
include './partials/hero.php';
include './partials/services.php';
include './partials/contact.php';
include './partials/footer.php';
?>

Each partial accesses blocks directly:

<?php
// partials/hero.php
$hero = $blocks['hero'];
?>
<section class="hero">
    <div class="container">
        <h1><?php echo $hero['h1']; ?></h1>
        <p><?php echo $hero['h2']; ?></p>
        <?php if (isset($hero['image'])): ?>
            <img src="<?php echo $hero['image']; ?>" alt="">
        <?php endif; ?>
    </div>
</section>

Key Points:

  • get_data('content') loads page content
  • filter_blocks() removes :0 suffixes (e.g., hero:0hero)
  • Partials access blocks directly: $blocks['hero'], $blocks['services']
  • No HTTP requests, no serialization - just direct array access

Why This Approach?

This file inclusion architecture offers several advantages:

  1. Zero HTTP Overhead - No API requests, content accessed directly
  2. Extremely Fast - File system reads are faster than HTTP round trips
  3. Simple Deployment - Frontend and CMS in same hosting space
  4. Shared Session - Admin and frontend share PHP session naturally
  5. Easy Debugging - Direct function calls, clear error traces
  6. Minimal Footprint - No API layer, no serialization overhead

This makes ETVO Manage perfect for shared hosting environments where every MB counts and HTTP requests add latency.

💡 Why Build From Scratch?

The 1GB Challenge

A free hosting plan won't offer much more than 1GB of storage. Traditional CMSs with their dependencies, databases, and overhead often struggle to fit everything (CMS + content + media) within this limit. ETVO Manage was designed with this constraint in mind:

  • No Frameworks - Laravel, Symfony, etc. add 50-100MB+ of vendor files
  • No Database - MySQL/PostgreSQL require separate storage allocation
  • No Libraries - Every dependency adds weight
  • Optimized Media - Smart image processing and storage strategies

Result: A complete CMS that leaves most of your 1GB for actual content and media.

The Learning Achievement

Building a CMS from scratch provided deep insights into:

  • Authentication & Security - Session management, CSRF protection, XSS prevention
  • File System Operations - Efficient file handling, JSON parsing, media processing
  • API Design - RESTful principles, response formatting, error handling
  • Content Modeling - Flexible data structures, validation, relationships
  • Frontend Integration - Separation of concerns, API consumption patterns

🛠️ Tech Stack

  • Backend: Pure PHP (no frameworks or libraries)
  • Storage: JSON files (no database required)
  • Integration: Direct file inclusion (no REST API)
  • Media Handling: Custom image processing with GD Library
  • Authentication: Session-based with token verification
  • Frontend Agnostic: Use any PHP-capable frontend

📦 Installation

Requirements

  • PHP 7.4 or higher
  • Apache/Nginx with mod_rewrite
  • GD Library (for image processing)
  • 100MB minimum disk space (1GB recommended for content)

Quick Setup

# Clone the repository
git clone https://github.com/ETVO/etvo-manage.git
cd etvo-manage

# Set permissions for writable directories
chmod -R 755 content/
chmod -R 755 media/
chmod -R 755 config/

# Configure your web server to point to the project root

# Access index.php to initialize
# http://yourdomain.com/index.php

# Follow the setup wizard to create your first admin user
# Set name, username, and password

# You're ready to go!

Frontend Example

A complete frontend implementation example is available at github.com/ETVO/etvo-page, demonstrating how to consume the API and render content.

🎯 Use Cases

  • Personal Blogs - Lightweight solution for content creators
  • Portfolio Sites - Showcase work with custom content structures
  • Small Business Sites - Manage products, services, and content
  • Landing Pages - Quick content updates without developer involvement
  • Shared Hosting Projects - Perfect for environments where every MB counts
  • Multi-site Networks - Deploy multiple instances efficiently
  • Prototype Projects - Rapid development without setup overhead

🔐 Security Features

Despite being lightweight, ETVO Manage includes essential security measures:

  • Password Hashing - Uses PHP's password_hash() and password_verify() for secure credential storage
  • Session Management - 30-day session duration with expiration checking
  • Access Control - Role-based access levels (admin, etc.)
  • First-Run Initialization - Forces admin user creation on first access
  • SQL Injection Proof - No database = no SQL injection risk
  • File Upload Validation - Image type checking and 5MB size limit
  • Session Security - Automatic logout on session expiration or user deactivation

🌟 Advantages of the Architecture

ETVO Manage's file inclusion approach provides unique benefits:

  • Direct Content Access - No HTTP overhead, read JSON files directly
  • Shared Hosting Friendly - Frontend and CMS coexist in same space
  • Lightning Fast - File system reads faster than API calls
  • Simple Integration - Just include PHP files, no API client needed
  • Easy Debugging - Direct function calls with clear stack traces
  • Zero Network Latency - No HTTP round trips for content
  • Minimal Footprint - No API layer or serialization overhead
  • Session Sharing - Admin and frontend naturally share PHP session

📊 Performance Characteristics

  • Initial Load: < 50ms (no framework overhead)
  • API Response: < 100ms (direct file reads)
  • Memory Usage: < 20MB per request
  • Disk Space: ~10MB for CMS core
  • Concurrent Users: 50+ on shared hosting

🎓 Learning Outcomes

This project served as a comprehensive exercise in:

  • Core PHP Proficiency - Deep understanding without framework abstractions
  • System Architecture - Designing flexible yet constrained systems with intentional tradeoffs
  • Performance Optimization - Building efficient systems with minimal resources
  • Content Modeling - Balancing flexibility with simplicity for optimal UX
  • Problem Solving - Creative solutions within tight constraints (1GB challenge)
  • Security Implementation - Protecting applications without library dependencies
  • Architectural Decisions - Understanding when to limit flexibility for better performance and maintainability

🚧 Future Enhancements

Potential improvements while maintaining lightweight philosophy:

  • Multi-language Support - Internationalization for content
  • Revision History - Track content changes over time
  • Role-Based Access - Fine-grained permission system
  • Search Functionality - Full-text search across content
  • Webhook Support - Trigger actions on content events
  • Cache Layer - Optional caching for high-traffic sites
  • GraphQL Endpoint - Alternative to REST API

👤 Author

Estevão Pereira Rolim - @ETVO | LinkedIn

Full Stack Developer with 8 years of experience specializing in PHP and JavaScript. Built ETVO Manage as a personal challenge to create a production-ready CMS without frameworks or external dependencies, proving that powerful tools can be remarkably lightweight.


Built with pure PHP and determination. No frameworks. No libraries. No API overhead.

This project demonstrates that modern CMSs don't need REST APIs or complex architectures - direct file inclusion can deliver powerful features with minimal footprint and maximum performance.

README generated in collaboration with Claude AI.

About

Lightweight headless CMS built from scratch with PHP and JSON files. Zero-dependency architecture with block-based editing, using only ~10MB of disk.

Topics

Resources

Stars

Watchers

Forks

Contributors