Etikett bokarenan.se

Uppdaterade nyheter

Hej kära vänner och läsare! Det är fredag och helg. Många av oss sätter oss i soffan ikväll med chips och tittar på något underhållande. De senaste veckorna har jag och min sambo kunnat njuta av den dumma (men roliga!) tv-serien Medical Police på Netflix. Tyvärr var det bara 10 avsnitt så nu får vi ägna oss åt något annat. Men eftersom det är fredag så skriver jag veckans sista inlägg så här på eftermiddagen. Den här veckan har fokus varit på programmering och att lägga till en blogg-funktion till Bokarenan. I onsdags skrev jag om hur Symfony och Doctrine har underlättat skapandet av en ny entitet (BlogPost) och uppdateringen av databasen. Denna gång ska jag skriva om den avslutande delen: hur allt ska kunna presenteras till användaren.

Det finns två komponenter att beakta när det kommer till hur nyheterna presenteras till användarna: template och Controller. Jag tänkte börja med Controller.

Min tanke är att den som är administratör ska kunna skriva ett blogginlägg (nyhet). Jag löste detta genom att använda AdminController och lägga till två funktioner till denna Controller som jag alltså har haft sedan tidigare. Den första funktionen innebär att administratören kan lägga till ett nytt inlägg. Något som jag vill lyfta fram som några detaljer är att administratören kan välja publiceringsdatum. Det innebär att inläggen inte dyker upp under Nyheter om inte publiceringsdatumet har nåtts. Den andra detaljen jag vill lyfta fram är ”slugs”. Det innebär att varje inlägg har en unik länk i stil med 2020-01-31-Det_här_är_en_nyhet. Detta kommer till användning när man vill titta på endast en nyhet, eller för sökmotorers möjligheter att länka direkt till ett inlägg.

Den andra Controllern som behövde uppdateras var NewsController. Denna kontroller har tilluppgift att presentera nyheter till användare. I kontrollern så skapade jag en ny funktion som hämtar de senaste inläggen och skickar dem till template-engine. Det tillkommer lite fler detaljer som innebär att jag kan paginera allt ihop och bara hämta de inlägg som ska vara på den aktuella sidan som användaren är på. Oftast är detta första sidan, men länkar till övriga sidor dyker upp längst ned.

Vad är då template-engine? Det är i princip en funktion som renderar html (eller php-filer med html-element) med dynamiskt innehåll. Som template-engine använder jag Twig. Från NewsController skickar jag de aktuella inläggen till Twig som löser det hela med att placera innehåll på rätt ställen och presenterar det med html-element och innehåll till användaren.

I NewsController så kan det se ut så här:

    /**
     * @Route("/{page}", name="nyheter_index", methods={"GET"})
     */
    public function index(BlogPostRepository $blogRepository, $page=1): Response
    {
        if (!\is_numeric($page)) {
            $page=1;
        }

        
        $count = $blogRepository->getCount();
        $limit = 1;
        $pages = $count/$limit;
        $pages = \ceil($pages);
        if ($page > $pages) {
            $page = $pages;
        }
        $posts = $blogRepository->getLatest($page, $limit);
        return $this->render("nyheter/index.html.twig", [
            "count" => $count,
            "page" => $page,
            "pages" => $pages,
            "posts" => $posts
        ]);
    }

Man kan se att det finns en template fil under filmappen nyheter som heter index.html.twig. Den filen ser ut så här:

{% extends "content.html.twig" %}
{% block navNyheter %}active{% endblock %}
{% block content %}
    {% for post in posts %}
        <article>
            <div class="article-header">
                <h1><a href="{{ path("nyheter_view", {'slug': post.slug}) }}">{{ post.title }}</a></h1>
            </div>
            <div class="article-content">
                <p class="time">{{ post.publish|date("d/m/Y") }} av {{ post.user }}</p>
                <p>{{ post.text|striptags('<em><strong><i><mark><cite><dfn>')|raw|nl2br }}</p>
                {% if app.user == post.user %}
                    <p><a href=""></a></p>
                {% endif %}
                
            </div>
        </article>
    {% endfor %}
    <div class="flex-center">
        {% for i in 1.. pages %}
            {% if i == page %}
                <a class="page-number active" href="/nyheter/{{i}}">{{ i }}</a>
            {% else %}
                <a class="page-number" href="/nyheter/{{i}}">{{ i }}</a>
            {% endif %}
        {% endfor %}
    </div>
{% endblock %}

Som man kan se i ovanstående kod så kan jag komma åt variabeln $posts genom instruktionen {{ post }}. Och när jag använder det på rätt sätt så kan jag få ett resultat som liknar det nedan.

Så det var allt för denna gången. Jag har skrivit ett blogginlägg om att göra en bloggfunktion för att göra blogginlägg. Blogg. Nu har jag skrivit det så mycket att jag börjar läsa det hela som grogg. Och apropå det: spel! Jag har visserligen en viss varm känsla för Secret of Monkey Island, men något som jag ser fram emot nu är att börja spela Skyrim igen. Senast jag gjorde det var 2013. Nu har jag den uppdaterade versionen på PS4. Jag får se om det fortfarande kan hålla mig underhållen. Men det är lugnt. Jag har några partyspel som nog funkar gott ändå!

Trevlig helg, allihopa!


Att göra en nyhetsblogg

Denna onsdag skriver jag om Bokarenan och möjligheten att bygga på den med fler funktioner. Det som står på dagordningen denna gång är en nyhetsblogg. För att få till detta så är det tre saker som ska komma på plats:

  • Ny entitet
  • Uppdaterad databas
  • Uppdaterad presentation/view

Det enklaste är att skapa en ny entitet med hjälp av MakerBundle i Symfony. Det innebär att jag via ett CLI (kommandotolken) kan instruera Symfony att göra den nya entiteten åt mig. På vägen får jag hjälp av Symfony för vad jag ska göra härnäst. För att starta det hela så utgår jag från projektets root-mapp och kör följande kommando:
php .\bin\console make:entity

Detta ger följande interaktion:

Jag döper min nya entitet till BlogPost, och ger den följande fält:
– title [string]
– text [text]
– entered [datetime]
– modified [datetime]
– publish [datetime]
– user [ManyToOne]

Exempel på hur fältet user i BlogPost relaterar till en annan entitet. User är det objekt som alltså refereras av BlogPost. ManyToOne innebär att respektive BlogPost bara kan referera till en användare, men en användare kan skapa flera BlogPost.

Genom hela denna process så har Symfony skapat och uppdaterat klassen BlogPost. Om vi tar en översikt över kursen så har den följande metoder och fält:

Då var steg ett avklarat. Nästa steg är att uppdatera databasen. Återigen är Symfony behjälplig… eller rättare sagt så är det faktiskt Doctrine. I CLI:t så kör jag följande kommandon:
php .\bin\console make:migration
Detta är en instruktion från Symfony till Doctrine hur databasen ska uppdateras efter att en till entitet har lagts till. Då återstår att låta Doctrine uppdatera databasen:
php .\bin\console doctrine:migrations:migrate
Databasen är nu uppdaterad och har rätta relationerna mellan BloggPost-tabellen och User-tabellen.

Då var två av tre steg avklarade. Det som återstår nu är att uppdatera presentationen för denna nya entitet. Detta steg består faktiskt av flera detaljer. Det innebär att en kontroller (eller två) ska uppdateras, en template för att skapa bloggposter ska skapas, en template för att presentera bloggposter ska uppdateras. Detta steg återkommer jag till på fredag. Vi ses då!