Kako smo napravili naš blog Cover

Kako smo napravili naš blog

Matej Arlović – 16/07/2020

Već neko vrijeme razmišljam o Master Games blogu gdje bismo svi iz tima djelili novosti o razvoju novih proizvoda i tutorijale vezane uz game i web development. Kada sam dobio zadatak da za završetak kolegija moram napraviti nešto u PHP-u odmah sam krenuo raditi vlastiti blog engine!

Zašto sam izgradio vlastiti blog engine?

Prije no što sam dobio zadatak za pravljenje bloga u PHP-u sam dugo razmišljao o WordPressu kao CMS za Master Games blog. WordPress sam koristio za potrebe bloganja o gaming zajednici koju sam vodio i bio sam upoznat kako on radi. No WordPress je kompleksan CMS koji ima stvari koje nama nisu trebale, poput plugin sistema i blog tema. Što je više stvari under the hood, to je potrebnije imati bolje peformanse na web hostu. 

Izrada vlastitog blog engine-a

Blog engine sam napravio u Laravelu 7. Ako slučajno ne znate što je Laravel - to je jedan od najpopularnijih open source PHP framework-ova dostupnih na internetu! Prije nekoliko godina sam radio vlastitu verziju Instagrama u Laravelu i jako mi se svidjelo što su olakšali web developerima izgradnju vlastitih sustava jer su u pozadini riješili jako puno problema. Želiš učitati datoteku na server? 

$path = $request->file('avatar')->store('avatars');

Bum - gotovo! Doduše, gore navedeni kod će generirati UUID naziv datoteke, ali s drugom funkcijom možete vrlo lako navesti naziv datoteke kada bude uploadana na server. Osim toga, unutar Laravela postoji i wrapper za webpack pod nazivom Laravel Mix. S Laravel Mix-om vrlo lako možete spojiti više JavaScript ili CSS datoteka u veće datoteke koje se (ovisno o opciji) mogu dodatno smanjiti. Laravel Mix sam iskoristio kako bih spojio sve JavaScript i CSS datoteke u dvije velike datoteke, jer se tako smanjuje broj HTTP zahtjeva koje internet preglednik šalje serveru (osim ako preglednik nije spremio te datoteke u lokalni keš). Samim time se brže učitava stranica. Novi blog mora imati:

  • Jednostavnost— Ne smije zauzimati puno performansi servera
  • Brzinu — Stranice se moraju učitavati brzinom svjetlosti
  • Admin panel — na kojem će se: registrirati korisnici, postavljajti i uređivati postovi i gdje će postojati mjesto za uređivanje osnovnih postavki bloga
  • WYSIWYG editor — Korisniku odmah prikazuje dizajn i sadržaj blog posta
  • SEO friendly — Mora imati automatsko generiranje sitemap.xml datoteka i imati sve popratne SEO sadržaje poput breadcrumbs, Open Graph Protocol, Twitter cards & JSON-LD
  • Responzivnost — Svi sadržaji bloga moraju biti dostupni i na mobilnim uređajima
  • Lokalizacija — Linkovi i određeni sadržaji bloga moraju biti lokalizirani na hrvatski i engleski (da možete ovo čitati i na engleskom!)

Bilo je jako puno ciljeva (a malo vremena) stoga sam se odmah bacio na izradu engine-a.

Master Games Blog - Trello Board

Postavio sam Trello s početnim ciljevima i odmah se bacio na instaliranje Laravela i ostalih stvari koje su mi bile potrebne za početak rada. 

Infrastruktura

Odmah pri instaliranju htio sam se riješiti jalovog posla i instalirati pakete koji bi mi skratili vrijeme izrade, ali i donijeli dodatne funkcionalnosti bloga.

Iskreno, mogao sam napisati vlastiti kod za gore navedene pakete, ali su me učili da ne izmišljam toplu vodu i da koristim javno dostupne kodove za stvari koje radim. Odmah na početku sam imao gotov blog, no trebalo je dodati još stvari i sve to ukombinirati u dizajn. Laravel projekti se rade u MVC arhitekturi stoga je i ovaj blog rađen u toj arhitekturi. Sve je podijeljeno u modele (koji čuvaju podatke), view (koji prikazuju obrađeni podatak) i controller (koji obrađuju podatke). Dole je prikazan model za blog postove:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Posts extends Model
{
    use \Conner\Tagging\Taggable;
    use \Rinvex\Categories\Traits\Categorizable;
    use \Spatie\Translatable\HasTranslations;
    
    /**
     * The attributes that are translatable.
     *
     * @var array
     */
    public $translatable = ['title', 'slug', 'body'];

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'title', 'slug', 'cover_img', "body", "online"
    ];

    /**
     * The method that have relationship with another table in DB.
     */
    public function author() 
    {
        return $this->belongsTo('App\User', 'author_id');
    }

    /**
     * The method returns created_at time formated with ISO 8601.
     */
    public function create_time()
    {
        return $this->created_at->format('c');
    }
}

Iz gore navedenog modela se generira kontroler koji se bavi obradom podataka. Da bi se napravila HTTP ruta koja koristi funkcije iz kontrolera unutar routes.php je dovoljno napisati sljedeću liniju koda:

Route::resource('posts', 'PostsController');

Ova jedna linija koda definira HTTP rutu za sve RESTful akcije unutar photo resursa (modela). U dolje prikazanoj tablici su prikazane sve akcije kojim upravlja kontroler:

Master Games Blog - Prikaz HTTP rute iz generiranog resursa (izvor: Laravel.com)

Admin panel

Admin panel (dashboard) omogućava autorima bloga jednostavno uređivanje blog postova i njegovih osnovnih postavki. Zbog sigurnosnih rizika i jer nije bila potrebna javna registracija, registracija novog korisnika (autora) se vrši putem dashboard-a.

Master Games Blog - Prikaz dashboarda

Kao i na javnom dijelu bloga, i dashboard je responzivan što omogućuje autorima da putem mobitela pregledaju ili objave postove.

WYSIWYG editor

Za WYSIWYG editor sam odabrao CKEditor jer je besplatan i jer pruža pogodnosti poput Google Docsa ili MS Worda. Jednostavno se može kopirati bilo koji tekst iz MS Office programa ili Google Docsa i taj tekst će s istim uređenjem biti prikazan unutar editora. 

Master Games Blog - Prikaz editora za objavu postova

Osim toga želio sam editor koji će se moći brzo mijenjati preko JavaScript koda jer želim omogućiti blogerima da pišu blog postove na više jezika. U gornjem desnom uglu se nalazi menu za odabir jezika. Kada se promijeni jezik tada se mijenjaju i polja za unos naslova i teksta.

$(".bp-body-inputs").each((index, element) => {
 
    if (index == 0) {
 
        $(element).show();
        CKEDITOR.replace($(element).attr('id'), {
            customConfig: "{{ asset('/js/ckeditor/config.js') }}"
        });
    } else {
        $(element).hide();
    }
});
 
$("#bp-locale-menu li a").click((e) => {
 
    e.preventDefault();
    const value = $(e.currentTarget).data('value');
    $(e.currentTarget).parents(".dropdown").find('.dropdown-toggle').html($(e.currentTarget).text() + ' <span class="caret"></span>');
    $(e.currentTarget).parents(".dropdown").find('.dropdown-toggle').val(value);
 
    $(".bp-title-inputs").each(function (index, element) {
 
        $(element).hide();
        if ($(element).data('value') == value) {
            
            $(element).show();
        }
    });
 
    $(".bp-body-inputs").each(function (index, element) {
 
        if(CKEDITOR.instances[$(element).attr('id')] !== undefined) {
            CKEDITOR.instances[$(element).attr('id')].updateElement();
            CKEDITOR.instances[$(element).attr('id')].destroy();
        }
 
        if ($(element).data('value') == value) {
 
            $(element).show();
            bodyTextArea = element;
            CKEDITOR.replace($(element).attr('id'), {
                customConfig: ''
            });                 
        } else {
            $(element).hide();
        }
    });
});

Unutar pedesetak linija koda se omogućuje pisanje blog postova na više jezika. Unutar postavka blog engine-a se određuju jezici. Tekst se sprema kao polje JSON objekata čiji su ključevi ISO-15897 znakovi jezika (npr. “en”, “hr”, itd.). Unutar JSON objekta se sprema HTML verzija blog posta koja se nakon toga bez dodatnog formatiranja prikazuje na javnom dijelu bloga.

Search Engine Optimization (SEO)

Nisam neki SEO genijalac, ali otprilike znam koje su stvari potrebne da se web stranica (u ovom slučaju blog) gurne na vrh pretraživanja.

  • Open Graph Protocol — Omogućava stranici da postane “graph object” na društvenoj mreži (poput Facebooka) odnosno prikazuje naslovnu sliku i naslov web stranice kada postavite link na društvenoj mreži
  • Twitter Cards — Isto kao OGP, ali samo za Twitter
  • JSON-LD breadcrumbs — Svaki blog treba imati breadcrumbs (doslovni prijevod je: mrvice kruha) kako bi tražilica znala kojim linkovima treba proći da bi došla do trenutne stranice
  • Meta Tags — Meta tagovi za naslov i opis stranice utječu za SEO stranice. Njih autor bloga može promjeniti u postavkama 

Open source projekt

Master Games Blog je hostan na GitHub-u kao javan repozitorij. Bilo tko može pregledati i uređivati kod. Slobodno možete uređivati kod kako pristaje Vašim potrebama. 

Master Games Blog - GitHub repozitorij

Bug fixevi i nove značajke su dobrodošle, a više o ažuriranju izvornog koda projekta će biti dostupno u README.md datoteci na Master Games - Blog repozitoriju!

Što sam naučio iz ovoga?

Moram priznati da je razvoj trajao duže nego što sam to predviđao. Najviše vremena je uzeo dizajn dashboarda i javnog dijela bloga. Dio dizajna javnog dijela bloga je preuzet sa Master Games-ove web stranice, ali je trebalo urediti prikaz postova i autora. 

Ipak, sve je vrijedilo svake potrošene minute i popijene šalice kave! Naučio sam dosta dodatnog o MVC-u i Laravel-u što inače ne bih naučio jer mi nije “trebalo”. Vlastiti blog engine je dvostruki mač jer s jedne strane možete prilagođavati blog kako vama treba, ali se također može dogoditi da ne predvidite neke sigurnosne pogreške koje mogu dovesti do rušenja stranice i dodatnih glavobolja oko backupa itd.

Postani dio Master Games zajednice na Facebook-u i Twitter-u!

Podjeli post:
Matej Arlović's Avatar
Napisao:

Matej Arlović

Matej Arlović je osnivač Master Games studija. Matej je osnovao Master Games tijekom srednjoškolskih dana. Voli programiranje, video igre i glazbu. Test