Blog / Tehnologija i razvoj / Custom CMS

Kako napraviti custom CMS
za malu poslovnu web stranicu

Custom CMS ne mora biti velika platforma. Za malu poslovnu web stranicu često je bolje napraviti jednostavan, namjenski sustav koji pokriva stvarne potrebe: stranice, blog, slike, SEO polja, objavu sadržaja i sigurnu administraciju.

Custom CMS arhitektura za malu poslovnu web stranicu

Ako klijent treba uređivati nekoliko usluga, blog objave, reference, fotografije i osnovna SEO polja, ne mora uvijek trebati univerzalni CMS s page builderom, pluginovima i velikim administracijskim slojem. Ponekad je bolji custom CMS koji radi manje stvari, ali ih radi jasno, brzo i sigurno.

Glavna ideja: CMS za malu poslovnu web stranicu treba uređivati sadržaj, a ne postati proizvod za sebe. Ako administracija ima 80 opcija koje klijent nikad neće koristiti, vjerojatno ste ugradili previše generičke kompleksnosti.

1. Prvo definirajte što CMS stvarno mora uređivati

Najveća greška u izradi custom CMS-a je krenuti od tehnologije umjesto od sadržaja. Prije baze, admin panela i klasa treba znati koje entitete klijent stvarno treba uređivati. Mala poslovna stranica obično ima statične stranice, usluge, blog objave, reference, slike i osnovne globalne postavke.

Ne treba odmah graditi sustav za sve moguće scenarije. Bolji pristup je napraviti stabilnu jezgru i dodavati module samo kada postoji stvarna potreba. CMS po mjeri ima smisla upravo zato što se ne mora ponašati kao univerzalna platforma.

Modul
Što uređuje
Zašto je važan
Stranice
Naslov, slug, sadržaj, hero slika, SEO polja.
Glavne javne stranice moraju imati stabilan URL i canonical.
Blog
Objave, kategorije, excerpt, slika, published stanje.
Blog gradi topical authority i interni linking prema money stranicama.
Reference
Projekt, opis, djelatnost, slike, linkovi.
Reference grade povjerenje i podržavaju prodajni proces.
Media library
Upload, WebP izvedenice, alt tekst, dimenzije.
Slike su performance, SEO i accessibility element.

2. Minimalna struktura baze

Za jednostavan CMS ne treba previše tablica, ali treba izbjeći i jednu ogromnu tablicu koja sadrži sve. Dobar početak je imati tablice za korisnike, stranice, blog objave i media assete. Ako projekt ima više jezika, verzioniranje ili složen workflow, struktura se širi.

SQL Primjer pages tablice
CREATE TABLE pages (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(180) NOT NULL,
    slug VARCHAR(180) NOT NULL UNIQUE,
    meta_title VARCHAR(180) NULL,
    meta_description VARCHAR(255) NULL,
    excerpt TEXT NULL,
    body MEDIUMTEXT NOT NULL,
    hero_image_id INT UNSIGNED NULL,
    status ENUM('draft', 'published') NOT NULL DEFAULT 'draft',
    published_at DATETIME NULL,
    created_at DATETIME NOT NULL,
    updated_at DATETIME NOT NULL
);

Ovdje su SEO polja dio sadržajnog modela, a ne naknadna misao. Ako urednik može promijeniti naslov stranice, treba moći promijeniti i meta title, opis, excerpt i sliku za dijeljenje.

3. Slug i canonical moraju biti pod kontrolom

CMS treba omogućiti uređivanje sluga, ali ne smije ga mijenjati automatski svaki put kada se promijeni naslov. Jednom kada URL uđe u sitemap, interne linkove i Google indeks, slug postaje stabilan identitet stranice. Ako se mijenja, treba 301 redirect.

PHP Page model s canonical helperom
<?php

final readonly class CmsPage
{
    public function __construct(
        public int $id,
        public string $title,
        public string $slug,
        public string $status,
        public ?string $metaTitle,
        public ?string $metaDescription,
    ) {}

    public function canonicalUrl(string $baseUrl): string
    {
        return rtrim($baseUrl, '/') . '/' . trim($this->slug, '/');
    }

    public function isPublished(): bool
    {
        return $this->status === 'published';
    }
}

Za URL disciplinu pogledajte i vodič kako strukturirati URL-ove za SEO, jer CMS treba proizvoditi URL-ove koji dugoročno ostaju stabilni.

4. Repository sloj drži SQL izvan templatea

Template ne bi trebao znati kako se dohvaća stranica iz baze. Ako se SQL nalazi direktno u view datoteci, s vremenom je teže testirati, održavati i mijenjati logiku. Jednostavan repository sloj dovoljan je da CMS ostane čitljiv.

PHP / PDO Dohvat objavljene stranice po slugu
<?php

final class PageRepository
{
    public function __construct(private PDO $db) {}

    public function findPublishedBySlug(string $slug): ?array
    {
        $stmt = $this->db->prepare(
            'SELECT id, title, slug, meta_title, meta_description, body
             FROM pages
             WHERE slug = :slug AND status = :status
             LIMIT 1'
        );

        $stmt->execute([
            'slug' => $slug,
            'status' => 'published',
        ]);

        $page = $stmt->fetch(PDO::FETCH_ASSOC);

        return $page ?: null;
    }
}

5. Draft i published workflow

Čak i mali CMS treba razlikovati draft i published sadržaj. Urednik treba moći pripremiti stranicu bez da je odmah javna. Javni router treba prikazivati samo objavljene stranice, dok admin može vidjeti draftove. Preview opcija je korisna, ali treba paziti da preview URL ne postane indeksiran.

Workflow pravila

  • Draft stranice ne smiju biti u sitemapu.
  • Draft stranice ne smiju biti dostupne javno bez autorizacije.
  • Published stranice moraju imati canonical URL.
  • Promjena sluga na published stranici treba ponuditi 301 redirect.
  • Brisanje published stranice treba imati odluku: redirect, 404 ili 410.

6. SEO polja su dio CMS-a, ne plugin

Kod CMS-a po mjeri nema potrebe za SEO pluginom ako znate koja polja trebate. Meta title, meta description, canonical URL, OG/Twitter slika, alt tekst, excerpt i schema tip mogu biti dio osnovnog modela. Time urednik dobiva kontrolu, a developer zadržava dosljedan output.

PHP Meta fallback logika
<?php

function page_meta(array $page): array
{
    return [
        'title' => $page['meta_title'] ?: $page['title'],
        'description' => $page['meta_description'] ?: $page['excerpt'] ?? '',
        'canonical' => canonical_url('/' . $page['slug']),
        'image' => $page['hero_image'] ?? '/assets/images/default-og.webp',
    ];
}

Ovakva fallback logika je mala, ali važna. CMS ne smije završiti s praznim title tagom, nepostojećim opisom ili pogrešnom slikom za dijeljenje.

7. Media library i slike

Ako CMS dopušta upload slika, mora ih kontrolirati. Originalne slike često dolaze prevelike, u krivom formatu ili bez alt teksta. Dobar CMS treba spremiti original ako treba, ali javnom webu servirati optimizirane izvedenice.

SQL Media tablica za slike
CREATE TABLE media_assets (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    filename VARCHAR(255) NOT NULL,
    path VARCHAR(255) NOT NULL,
    mime_type VARCHAR(80) NOT NULL,
    width INT UNSIGNED NOT NULL,
    height INT UNSIGNED NOT NULL,
    alt_text VARCHAR(255) NULL,
    created_at DATETIME NOT NULL
);

Za detalje oko formata, dimenzija i lazy loadinga, povezano je korisno pročitati optimizaciju slika za web.

8. Admin forme: validacija i CSRF

Admin sučelje je sigurnosno osjetljivije od javnog dijela weba. Svaka forma treba CSRF token, server-side validaciju i provjeru autorizacije. Ako CMS ima upload slika, treba provjeriti MIME tip, veličinu, dimenzije i ekstenziju.

PHP CSRF provjera u admin handleru
<?php

function require_valid_csrf(array $post, array $session): void
{
    $token = (string) ($post['csrf_token'] ?? '');
    $expected = (string) ($session['csrf_token'] ?? '');

    if ($token === '' || !hash_equals($expected, $token)) {
        http_response_code(403);
        exit('Invalid CSRF token');
    }
}

Sigurnosni principi su slični kao kod kontakt forme. Ako vas zanima taj dio detaljnije, pogledajte članak sigurna PHP kontakt forma preko SMTP-a.

9. Role i prava pristupa

Mali CMS često ima samo jednog administratora, ali čak i tada treba imati jasnu autorizaciju. Ako kasnije dodate urednika, bolje je da sustav već ima pojam role nego da se prava pristupa improviziraju po handlerima.

Rola
Može
Ne bi trebala
Admin
Upravljati korisnicima, postavkama, svim sadržajem.
Dijeliti isti račun s više osoba.
Editor
Uređivati stranice, blog i slike.
Mijenjati SMTP, deploy config ili korisnike.
Viewer
Pregledavati sadržaj i draftove.
Objavljivati ili brisati stranice.

10. Sitemap i cache invalidacija

Kada CMS objavi novu javnu stranicu, sitemap treba dobiti novi URL. Kada se sadržajno promijeni postojeća stranica, lastmod treba odražavati stvarnu promjenu. Ako se mijenja slika, CSS ili JS, treba razmišljati i o cache-busting verziji asseta.

PHP Filtriranje samo objavljenih URL-ova za sitemap
<?php

function public_sitemap_pages(PDO $db): array
{
    $stmt = $db->query(
        "SELECT slug, updated_at
         FROM pages
         WHERE status = 'published'
         ORDER BY updated_at DESC"
    );

    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

11. Kada custom CMS ima smisla, a kada ne

Custom CMS ima smisla kada projekt ima jasne i ograničene potrebe, kada je bitna brzina, SEO kontrola, sigurnost i jednostavno održavanje. Nema smisla ako klijent treba kompleksan marketplace pluginova, veliki urednički tim, napredno verzioniranje, workflow odobravanja ili funkcionalnosti koje već dobro rješava postojeća platforma.

Praktična odluka: ako CMS treba raditi 20 stvari, custom pristup može biti savršen. Ako treba raditi 200 stvari, prvo provjerite gradite li platformu, a ne poslovni web.

Zaključak: dobar custom CMS je mali, jasan i namjenski

Custom CMS za malu poslovnu web stranicu treba biti dovoljno jednostavan da ga klijent razumije i dovoljno discipliniran da developer zna gdje je svaka odgovornost. Stranice, SEO polja, slike, draft/published workflow, sigurnost i sitemap čine jezgru koja pokriva većinu stvarnih potreba poslovnog weba.

Ako je CMS dobro osmišljen, on ne usporava web i ne zaključava projekt u nepotrebnu kompleksnost. Naprotiv, postaje stabilan alat za rast sadržaja, SEO autoriteta i dugoročno održavanje. Za širu sliku custom pristupa pogledajte i custom web rješenja vs WordPress te PHP vs .NET za poslovne web stranice.

Custom web razvoj Razvoj po mjeri