497 lines
14 KiB
Markdown
497 lines
14 KiB
Markdown
|
|
# Philosophy
|
||
|
|
|
||
|
|
Understanding the principles and thinking behind FolderWeb.
|
||
|
|
|
||
|
|
## Core Idea
|
||
|
|
|
||
|
|
**Your file system is your content management system.**
|
||
|
|
|
||
|
|
FolderWeb embraces the simplest possible approach to web publishing: create a folder structure that mirrors your site hierarchy, drop files into folders, and they immediately become pages. No database, no admin panel, no build process.
|
||
|
|
|
||
|
|
## Design Principles
|
||
|
|
|
||
|
|
### 1. Just Enough, Nothing More
|
||
|
|
|
||
|
|
FolderWeb applies minimal PHP to enable modern conveniences while remaining maintainable for years or decades. Every feature must justify its existence by solving a real problem without creating new complexity.
|
||
|
|
|
||
|
|
**What this means:**
|
||
|
|
- No frameworks that might be abandoned
|
||
|
|
- No build tools that need maintenance
|
||
|
|
- No package managers introducing dependencies
|
||
|
|
- No abstractions unless they provide lasting value
|
||
|
|
|
||
|
|
**Example**: Instead of using a routing library, FolderWeb uses PHP's native file functions to map folders to URLs. This will work identically in 2025 and 2035.
|
||
|
|
|
||
|
|
### 2. Longevity Over Novelty
|
||
|
|
|
||
|
|
Code should outlive trends. FolderWeb prioritizes stability and backward compatibility over cutting-edge features.
|
||
|
|
|
||
|
|
**What this means:**
|
||
|
|
- Standard PHP (no exotic extensions)
|
||
|
|
- Plain HTML and CSS (no JavaScript required)
|
||
|
|
- Simple file formats (Markdown, INI)
|
||
|
|
- Conventions over configuration
|
||
|
|
|
||
|
|
**Why it matters**: A site built today should still work in 10 years without updates. The web's foundational technologies (HTML, CSS, PHP) change slowly and maintain backward compatibility.
|
||
|
|
|
||
|
|
### 3. Transparent and Readable
|
||
|
|
|
||
|
|
You should be able to open any file and immediately understand what it does. No magic, no hidden behavior.
|
||
|
|
|
||
|
|
**What this means:**
|
||
|
|
- Sparse, meaningful comments
|
||
|
|
- Descriptive function names
|
||
|
|
- Simple control flow
|
||
|
|
- Minimal abstraction layers
|
||
|
|
|
||
|
|
**Example**: Want to know how templates work? Open `app/rendering.php` and read 100 lines of straightforward PHP. No framework documentation needed.
|
||
|
|
|
||
|
|
### 4. Files Are Content
|
||
|
|
|
||
|
|
Your content lives in plain text files you can edit with any text editor. You own your content completely.
|
||
|
|
|
||
|
|
**What this means:**
|
||
|
|
- Content is portable (copy files, migrate easily)
|
||
|
|
- Version control friendly (Git tracks changes)
|
||
|
|
- No lock-in (files work without FolderWeb)
|
||
|
|
- Backup-friendly (copy a folder)
|
||
|
|
|
||
|
|
**Example**: Your entire site is a folder structure. Zip it, move it to another server, extract it, and it works. No database export/import, no migration scripts.
|
||
|
|
|
||
|
|
## What FolderWeb Is
|
||
|
|
|
||
|
|
### A File-Based Router
|
||
|
|
|
||
|
|
FolderWeb maps your folder structure to URLs:
|
||
|
|
```
|
||
|
|
content/blog/2025-11-02-post/ → yoursite.com/blog/2025-11-02-post/
|
||
|
|
```
|
||
|
|
|
||
|
|
That's it. No route definitions, no controllers, no configuration.
|
||
|
|
|
||
|
|
### A Content Renderer
|
||
|
|
|
||
|
|
FolderWeb converts Markdown to HTML, wraps it in templates, and serves it. Three steps:
|
||
|
|
1. Find content files
|
||
|
|
2. Convert to HTML
|
||
|
|
3. Wrap in template
|
||
|
|
|
||
|
|
### A Minimal Template System
|
||
|
|
|
||
|
|
FolderWeb provides just enough templating to avoid repetition:
|
||
|
|
- Base template for site structure
|
||
|
|
- Page template for content wrapper
|
||
|
|
- List templates for directory views
|
||
|
|
|
||
|
|
All using plain PHP includes. No template language to learn.
|
||
|
|
|
||
|
|
### A Convention Framework
|
||
|
|
|
||
|
|
FolderWeb establishes conventions that eliminate configuration:
|
||
|
|
- `metadata.ini` for structured data
|
||
|
|
- `cover.jpg` for images
|
||
|
|
- `YYYY-MM-DD-slug` for dates
|
||
|
|
- `filename.lang.ext` for translations
|
||
|
|
|
||
|
|
Learn the conventions once, apply them everywhere.
|
||
|
|
|
||
|
|
## What FolderWeb Is Not
|
||
|
|
|
||
|
|
### Not a CMS
|
||
|
|
|
||
|
|
No admin panel. Edit files directly with your text editor, commit to Git, deploy.
|
||
|
|
|
||
|
|
**Why**: Admin panels add complexity, require maintenance, create security risks, and limit what you can do. Text files are simpler and more powerful.
|
||
|
|
|
||
|
|
### Not a Static Site Generator
|
||
|
|
|
||
|
|
FolderWeb renders pages on request, not at build time.
|
||
|
|
|
||
|
|
**Why**: No build step means immediate feedback. Save a file, refresh your browser, see changes. No waiting for builds, no deployment pipelines required (though you can add them).
|
||
|
|
|
||
|
|
### Not a JavaScript Framework
|
||
|
|
|
||
|
|
Zero JavaScript in the framework. HTML and CSS only.
|
||
|
|
|
||
|
|
**Why**: JavaScript adds complexity, breaks without it, requires builds/transpilation, and changes rapidly. HTML and CSS are stable and sufficient for content sites.
|
||
|
|
|
||
|
|
### Not Opinionated About Design
|
||
|
|
|
||
|
|
FolderWeb provides minimal default styles. Your design is your own.
|
||
|
|
|
||
|
|
**Why**: Design trends change. FolderWeb gives you a clean foundation and gets out of the way. Override everything in `/custom/`.
|
||
|
|
|
||
|
|
## Design Decisions Explained
|
||
|
|
|
||
|
|
### Why PHP 8.4+?
|
||
|
|
|
||
|
|
**Modern features without complexity.**
|
||
|
|
|
||
|
|
PHP 8.4 provides:
|
||
|
|
- Readonly classes (immutability)
|
||
|
|
- Property hooks (computed properties)
|
||
|
|
- Arrow functions (concise code)
|
||
|
|
- Modern array functions
|
||
|
|
- Asymmetric visibility (controlled access)
|
||
|
|
|
||
|
|
These features make code clearer without adding dependencies or build steps. PHP 8.4 will be supported for years.
|
||
|
|
|
||
|
|
**Tradeoff**: Requires newer PHP, but gains clarity and performance.
|
||
|
|
|
||
|
|
### Why No Database?
|
||
|
|
|
||
|
|
**Files are simpler.**
|
||
|
|
|
||
|
|
Databases add:
|
||
|
|
- Setup complexity
|
||
|
|
- Backup complexity
|
||
|
|
- Migration complexity
|
||
|
|
- Performance tuning
|
||
|
|
- Additional failure points
|
||
|
|
|
||
|
|
For content sites, files provide:
|
||
|
|
- Version control integration
|
||
|
|
- Simple backups (copy folder)
|
||
|
|
- Portability
|
||
|
|
- Transparent storage
|
||
|
|
- No setup required
|
||
|
|
|
||
|
|
**When you might need a database**: User-generated content, real-time updates, complex queries, thousands of pages. For those cases, use a different tool.
|
||
|
|
|
||
|
|
### Why INI Files for Metadata?
|
||
|
|
|
||
|
|
**Simple, readable, PHP-native.**
|
||
|
|
|
||
|
|
INI format:
|
||
|
|
- No parsing library needed (built into PHP)
|
||
|
|
- Human-readable and editable
|
||
|
|
- Supports sections for languages
|
||
|
|
- Familiar format
|
||
|
|
|
||
|
|
**Alternatives considered**:
|
||
|
|
- **YAML**: Requires library, complex syntax
|
||
|
|
- **JSON**: Not as human-friendly, no comments
|
||
|
|
- **TOML**: Requires library, less familiar
|
||
|
|
- **Frontmatter**: Mixes content and metadata
|
||
|
|
|
||
|
|
### Why Markdown?
|
||
|
|
|
||
|
|
**Readable as plain text, converts to HTML.**
|
||
|
|
|
||
|
|
Markdown is:
|
||
|
|
- Easy to learn (15 minutes)
|
||
|
|
- Readable without rendering
|
||
|
|
- Widely supported
|
||
|
|
- Future-proof (plain text)
|
||
|
|
- Version control friendly
|
||
|
|
|
||
|
|
**Alternatives supported**: HTML (for complex layouts), PHP (for dynamic content).
|
||
|
|
|
||
|
|
### Why No Build Tools?
|
||
|
|
|
||
|
|
**Immediate feedback, zero setup.**
|
||
|
|
|
||
|
|
Build tools add:
|
||
|
|
- Installation steps
|
||
|
|
- Configuration files
|
||
|
|
- Waiting for builds
|
||
|
|
- Build failures to debug
|
||
|
|
- Another thing that can break
|
||
|
|
|
||
|
|
Without builds:
|
||
|
|
- Save file → refresh browser → see result
|
||
|
|
- No setup (just PHP)
|
||
|
|
- Nothing to configure
|
||
|
|
- Nothing to break
|
||
|
|
|
||
|
|
**Tradeoff**: Can't use Sass, TypeScript, etc. But you can use modern CSS, which is very capable.
|
||
|
|
|
||
|
|
### Why Trailing Slashes?
|
||
|
|
|
||
|
|
**Consistency and clarity.**
|
||
|
|
|
||
|
|
```
|
||
|
|
/blog/ # Directory (list view)
|
||
|
|
/blog # Redirects to /blog/
|
||
|
|
```
|
||
|
|
|
||
|
|
Trailing slashes clarify that URLs represent directories, not files. Consistent URLs prevent duplicate content and simplify routing.
|
||
|
|
|
||
|
|
### Why Language Prefixes?
|
||
|
|
|
||
|
|
**Clear, hackable URLs.**
|
||
|
|
|
||
|
|
```
|
||
|
|
yoursite.com/en/about/ # English
|
||
|
|
yoursite.com/no/about/ # Norwegian
|
||
|
|
```
|
||
|
|
|
||
|
|
Language in URL:
|
||
|
|
- User sees current language
|
||
|
|
- Can manually change URL
|
||
|
|
- Bookmarkable per language
|
||
|
|
- SEO-friendly (clear language signal)
|
||
|
|
|
||
|
|
**Default language has no prefix** (shorter, cleaner URLs for primary audience).
|
||
|
|
|
||
|
|
## Architectural Patterns
|
||
|
|
|
||
|
|
### Immutable Context
|
||
|
|
|
||
|
|
The `Context` object is readonly (PHP 8.4):
|
||
|
|
```php
|
||
|
|
readonly class Context {
|
||
|
|
public function __construct(
|
||
|
|
public private(set) string $contentDir,
|
||
|
|
public private(set) string $currentLang,
|
||
|
|
// ...
|
||
|
|
) {}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Why**: Prevents accidental mutation, makes code predictable, enables safe sharing of state.
|
||
|
|
|
||
|
|
### Computed Properties
|
||
|
|
|
||
|
|
Properties calculate values on-demand:
|
||
|
|
```php
|
||
|
|
public string $langPrefix {
|
||
|
|
get => $this->currentLang !== $this->defaultLang
|
||
|
|
? "/{$this->currentLang}"
|
||
|
|
: '';
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Why**: Keeps related logic together, avoids storing derived data, updates automatically.
|
||
|
|
|
||
|
|
### Function-Based API
|
||
|
|
|
||
|
|
Core functionality exposed as functions, not classes:
|
||
|
|
```php
|
||
|
|
renderFile($ctx, $filePath);
|
||
|
|
findAllContentFiles($dir, $lang, $defaultLang, $availableLangs);
|
||
|
|
```
|
||
|
|
|
||
|
|
**Why**: Simple to understand, easy to test, no object lifecycle to manage.
|
||
|
|
|
||
|
|
### Template Fallback
|
||
|
|
|
||
|
|
Check custom, fall back to default:
|
||
|
|
```php
|
||
|
|
$custom = "/custom/templates/$name.php";
|
||
|
|
$default = "/app/default/templates/$name.php";
|
||
|
|
return file_exists($custom) ? $custom : $default;
|
||
|
|
```
|
||
|
|
|
||
|
|
**Why**: Never modify defaults, always override. Clean separation between framework and customization.
|
||
|
|
|
||
|
|
## Performance Philosophy
|
||
|
|
|
||
|
|
### Performance Through Simplicity
|
||
|
|
|
||
|
|
FolderWeb is fast because it does less:
|
||
|
|
- No database queries
|
||
|
|
- No heavy frameworks
|
||
|
|
- No JavaScript parsing
|
||
|
|
- Minimal file reads
|
||
|
|
- Direct PHP includes
|
||
|
|
|
||
|
|
**Measured performance**: Page load time displayed in footer. Pride in speed through simplicity.
|
||
|
|
|
||
|
|
### Caching Strategy
|
||
|
|
|
||
|
|
FolderWeb doesn't implement caching. Instead:
|
||
|
|
- Use OPcache (PHP bytecode cache)
|
||
|
|
- Use web server caching (Apache/Nginx)
|
||
|
|
- Use reverse proxy (Varnish, Cloudflare)
|
||
|
|
- CSS versioned automatically (MD5 hash)
|
||
|
|
|
||
|
|
**Why**: Let specialized tools handle caching. FolderWeb focuses on core functionality.
|
||
|
|
|
||
|
|
### Optimization Priorities
|
||
|
|
|
||
|
|
1. **Avoid work**: Don't render what's not needed
|
||
|
|
2. **Use native functions**: PHP's file functions are optimized
|
||
|
|
3. **Minimal abstraction**: Fewer layers = less overhead
|
||
|
|
|
||
|
|
## Security Philosophy
|
||
|
|
|
||
|
|
### Defense in Depth
|
||
|
|
|
||
|
|
Multiple security layers:
|
||
|
|
- Path validation (prevent directory traversal)
|
||
|
|
- Realpath checks (resolve symlinks, verify paths)
|
||
|
|
- Content root enforcement (files must be in document root)
|
||
|
|
- Output escaping (prevent XSS)
|
||
|
|
- MIME type validation (proper content types)
|
||
|
|
|
||
|
|
### Simplicity Is Security
|
||
|
|
|
||
|
|
Less code = smaller attack surface:
|
||
|
|
- No database (no SQL injection)
|
||
|
|
- No user input rendering (no XSS in content)
|
||
|
|
- No file uploads (no upload vulnerabilities)
|
||
|
|
- No authentication (no auth bypasses)
|
||
|
|
|
||
|
|
**For user-generated content**: Use a different tool. FolderWeb is for static content you control.
|
||
|
|
|
||
|
|
## Maintenance Philosophy
|
||
|
|
|
||
|
|
### Code Should Age Gracefully
|
||
|
|
|
||
|
|
FolderWeb aims to require zero maintenance:
|
||
|
|
- Standard PHP (no exotic dependencies)
|
||
|
|
- Minimal third-party code (one library: Parsedown)
|
||
|
|
- Stable APIs (PHP doesn't break backward compatibility)
|
||
|
|
- No framework upgrades needed
|
||
|
|
|
||
|
|
**Goal**: Deploy once, forget about it. Check in years later, it still works.
|
||
|
|
|
||
|
|
### Convention Over Configuration
|
||
|
|
|
||
|
|
Fewer configuration options = less to maintain:
|
||
|
|
- File conventions replace config
|
||
|
|
- Sensible defaults for everything
|
||
|
|
- Only configure what's necessary (languages)
|
||
|
|
|
||
|
|
### Documentation Is Core
|
||
|
|
|
||
|
|
Documentation is part of the project:
|
||
|
|
- Comprehensive reference
|
||
|
|
- Clear examples
|
||
|
|
- Explanation of decisions
|
||
|
|
- How-to guides for common tasks
|
||
|
|
|
||
|
|
**Why**: Future you (or someone else) will thank present you.
|
||
|
|
|
||
|
|
## When to Use FolderWeb
|
||
|
|
|
||
|
|
### Ideal For
|
||
|
|
|
||
|
|
- **Blogs**: Write Markdown, publish immediately
|
||
|
|
- **Documentation**: Multi-file pages, clear structure
|
||
|
|
- **Portfolios**: Grid layouts, cover images
|
||
|
|
- **Marketing sites**: Static content, fast loading
|
||
|
|
- **Personal sites**: Simple, maintainable
|
||
|
|
- **Long-term projects**: Will work for decades
|
||
|
|
|
||
|
|
### Not Ideal For
|
||
|
|
|
||
|
|
- **User-generated content**: No database, no auth
|
||
|
|
- **E-commerce**: Needs dynamic inventory, checkout
|
||
|
|
- **Social networks**: Real-time updates, complex data
|
||
|
|
- **SPAs**: JavaScript-heavy, API-driven
|
||
|
|
- **Large-scale sites**: Thousands of pages (consider static generation)
|
||
|
|
|
||
|
|
### Perfect Fit Scenario
|
||
|
|
|
||
|
|
You want a blog or content site that:
|
||
|
|
- You control all content
|
||
|
|
- Loads fast
|
||
|
|
- Requires minimal maintenance
|
||
|
|
- Will work for years without updates
|
||
|
|
- Integrates with Git workflow
|
||
|
|
- Gives you complete control
|
||
|
|
|
||
|
|
## Comparison to Alternatives
|
||
|
|
|
||
|
|
### vs WordPress
|
||
|
|
|
||
|
|
**WordPress**: Full-featured CMS, database-driven, plugin ecosystem, admin panel, requires regular updates
|
||
|
|
|
||
|
|
**FolderWeb**: File-based, no database, no plugins, no admin, zero maintenance
|
||
|
|
|
||
|
|
**Choose WordPress if**: You need plugins, non-technical editors, or a proven ecosystem
|
||
|
|
|
||
|
|
**Choose FolderWeb if**: You want simplicity, longevity, and complete control
|
||
|
|
|
||
|
|
### vs Jekyll/Hugo (Static Generators)
|
||
|
|
|
||
|
|
**Static Generators**: Build at deploy time, generate HTML files, fast serving, requires builds
|
||
|
|
|
||
|
|
**FolderWeb**: Renders on request, no build step, immediate feedback, simpler workflow
|
||
|
|
|
||
|
|
**Choose Static Generator if**: You want maximum performance, have build infrastructure
|
||
|
|
|
||
|
|
**Choose FolderWeb if**: You want immediate feedback, simpler deployment, dynamic capabilities
|
||
|
|
|
||
|
|
### vs Laravel/Symfony (PHP Frameworks)
|
||
|
|
|
||
|
|
**Frameworks**: Full-stack, MVC architecture, ORM, routing, complex features
|
||
|
|
|
||
|
|
**FolderWeb**: Minimal, file-based routing, no ORM, single purpose
|
||
|
|
|
||
|
|
**Choose Framework if**: You're building a complex web application
|
||
|
|
|
||
|
|
**Choose FolderWeb if**: You're publishing content and want simplicity
|
||
|
|
|
||
|
|
## Future Direction
|
||
|
|
|
||
|
|
### Stability Over Features
|
||
|
|
|
||
|
|
FolderWeb aims to reach "done" status:
|
||
|
|
- Core functionality complete
|
||
|
|
- No major features needed
|
||
|
|
- Focus on documentation and examples
|
||
|
|
- Bug fixes and security updates only
|
||
|
|
|
||
|
|
### Possible Additions
|
||
|
|
|
||
|
|
Only if they maintain simplicity:
|
||
|
|
- More template examples
|
||
|
|
- Additional default styles (opt-in)
|
||
|
|
- Performance optimizations
|
||
|
|
- Better error messages
|
||
|
|
|
||
|
|
### Will Never Add
|
||
|
|
|
||
|
|
Features that contradict philosophy:
|
||
|
|
- JavaScript requirement
|
||
|
|
- Database integration
|
||
|
|
- Build process
|
||
|
|
- Admin panel
|
||
|
|
- User authentication
|
||
|
|
- Complex plugin system
|
||
|
|
|
||
|
|
## Contributing to FolderWeb
|
||
|
|
|
||
|
|
### Align With Philosophy
|
||
|
|
|
||
|
|
Proposed changes should:
|
||
|
|
- Maintain simplicity
|
||
|
|
- Avoid new dependencies
|
||
|
|
- Work with PHP 8.4+
|
||
|
|
- Be maintainable long-term
|
||
|
|
- Solve real problems
|
||
|
|
|
||
|
|
### Ideal Contributions
|
||
|
|
|
||
|
|
- Bug fixes
|
||
|
|
- Performance improvements
|
||
|
|
- Better documentation
|
||
|
|
- Example templates
|
||
|
|
- Test cases
|
||
|
|
- Clarification of existing code
|
||
|
|
|
||
|
|
### Before Adding Features
|
||
|
|
|
||
|
|
Ask:
|
||
|
|
1. Can this be solved in userland (custom templates/code)?
|
||
|
|
2. Does this add complexity for all users?
|
||
|
|
3. Will this need maintenance in 5 years?
|
||
|
|
4. Is this truly necessary?
|
||
|
|
|
||
|
|
## Conclusion
|
||
|
|
|
||
|
|
FolderWeb is deliberately simple. It does one thing—publishes content from files—and does it well. It resists feature creep, embraces constraints, and prioritizes longevity.
|
||
|
|
|
||
|
|
This isn't the right tool for every project. But for content sites that value simplicity, maintainability, and longevity, it might be perfect.
|
||
|
|
|
||
|
|
The code you write today should work in 2035. FolderWeb is built on that principle.
|
||
|
|
|
||
|
|
## Related
|
||
|
|
|
||
|
|
- [Getting Started Tutorial](../tutorial/00-getting-started.md)
|
||
|
|
- [Architecture Overview](architecture.md)
|
||
|
|
- [File Structure Reference](../reference/file-structure.md)
|