Model–View–Controller
LavaLust is built around the Model–View–Controller (MVC) architectural pattern. MVC separates an application into three distinct layers — data, logic, and presentation — so each part of the codebase has a single, well-defined responsibility.
The practical benefit is that your views stay free of business logic, your controllers stay free of database queries, and your models stay free of presentation concerns. This makes the code easier to read, test, and maintain as a project grows.
Model
The Model is responsible for everything related to your data. It talks directly to the database and exposes clean methods that the controller can call — keeping raw queries out of the rest of the application.
Location: app/models/
Typical responsibilities:
Fetch rows from the database
Insert, update, and delete records
Encapsulate business rules that apply to the data (e.g. uniqueness checks, status transitions)
Return plain arrays or structured data to the controller
Example:
<?php
// app/models/Post_model.php
class Post_model extends Model
{
public function get_published($limit = 10)
{
return $this->db
->select('id, title, slug, created_at')
->table('posts')
->where('status', 'published')
->order_by('created_at', 'DESC')
->limit($limit)
->get();
}
public function find($id)
{
return $this->db
->table('posts')
->where('id', $id)
->get();
}
}
Note
Models are not required to use the database. A model can also wrap an external API, a file on disk, or any other data source.
View
The View is the presentation layer — it renders what the user actually sees. Views should contain only the HTML (or JSON/XML) needed to display data; they must not contain database calls or business logic.
Location: app/views/
A view in LavaLust is not limited to a full page. Common uses include:
View type |
Example |
|---|---|
Full HTML page |
|
Page fragment |
|
Email template |
|
RSS / XML feed |
|
JSON partial |
Rendered directly from the controller via |
Example:
<?php
// app/views/posts/index.php
?>
<h1>Latest Posts</h1>
<?php foreach ($posts as $post) : ?>
<article>
<h2><?= htmlspecialchars($post['title']) ?></h2>
<time><?= $post['created_at'] ?></time>
</article>
<?php endforeach; ?>
Views receive data from the controller as variables. They must never query the database or call models directly.
Controller
The Controller is the entry point for every request. It reads the incoming data, calls the appropriate model methods, and passes results to a view (or returns a response directly). It is the glue between the model and the view.
Location: app/controllers/
Typical responsibilities:
Receive and validate request input
Load and call model methods
Pass data to a view or build a JSON response
Handle redirects and error responses
Example:
<?php
// app/controllers/Posts.php
class Posts extends Controller
{
public function __construct()
{
parent::__construct();
$this->call->model('Post_model', 'post_model');
}
public function index()
{
$data['posts'] = $this->post_model->get_published(10);
$this->call->view('posts/index', $data);
}
public function show($id)
{
$post = $this->post_model->find((int) $id);
if ( ! $post)
{
$this->response->send_not_found('Post not found.');
return;
}
$this->call->view('posts/show', ['post' => $post]);
}
}
Note
Controllers must not contain database queries. Move any data access logic into a model to keep the controller focused on coordinating the request.
Responsibilities at a Glance
Layer |
Location |
Owns |
Must NOT contain |
|---|---|---|---|
Model |
|
Database queries, data rules, business logic |
HTML output, |
View |
|
HTML templates, presentation markup |
Database calls, business logic, redirects |
Controller |
|
Request handling, model coordination, response building |
Raw SQL queries, HTML markup |