Блог

Nuxtpress

Категорије:
  • ажурирања сајта

Не много после мог претходног писања, Nuxt.js-ов тим је објавио верзију 2.13, која доноси неколико нових додатака за Nuxt.js, међу којима су и @nuxt/components и @nuxt/content. Овај други додатак је званично решење за рад са чланцима у формату Markdown у Nuxt.js-у. Од тада сам у слободно време углавном радио на пребацивању свих делова мог сајта који имају везе са Markdown-ом на @nuxt/content. Осим овога, проучавао сам и начин на који се Nuxt апликација може писати у Typescript-у, што је једна од идеја за неки будући update. Вратимо се сад @nuxt/content-у.

Предности

Осим очигледне предности постојања готовог API-ја за читање чланака у формату Markdown, @nuxt/content нуди и напредно филтрирање и full-text претрагу преко интерфејса сличног MongoDB-у. Сада је довољно ставити .md фајлове у /content и може се написати, рецимо:

async asyncData({ $content })
{
    const latestArticles = await $content('/')
        .where({ type: { $eq: 'article' } })
        .sortBy('date', 'desc')
        .limit(5)
        .fetch();
    return {
        latestArticles,
    };
}

да би се учитало најсвежијих пет чланака сортираних по опадајућем редоследу. Претрага се такође обавља директно:

async asyncData({ $content, route })
{
    const foundArticles = await $content('/')
        .search(route.params.q)
        .fetch();
    return {
        foundArticles,
    };
}
    

Миграција

Главна разлика у односу на frontmatter-markdown-loader је што се у @nuxt/content-у уместо markdown-it-а за превођење Markdown-а у HTML користи remark. То значи да је за све plugin-ове markdown-it-а потребно користити еквиваленте, наравно уколико они постоје. На пример, за сада не постоји еквивалент pluginmarkdown-it-figure-caption.

Пошто је замисао @nuxt/content-а систем за управљање чланцима у виду фајлова, а не слогова у бази података, за сада не постоји уграђена подршка за складиштење чланака у бази уместо у фајл систему, па је потребно директно позивати remark. Наравно, могуће је напоредо са њим користити и markdown-it, али мислим да је то непотребно дуплирање зависности (dependencies) и није идеално. За сада још увек користим оба решења заједно, док не довршим подршку за приказивање текстова у одељку „Текстови“ уз помоћ remark-а.

Подршка за чланке

Категорије:
  • ажурирања сајта

Данас сам довршио додавање почетног система за приказивање чланака у Markdown-у. За разлику од тога како сам (за сада) реализовао приказивање чланака овог блога, у страницама из одељка „Текстови“ нисам користио frontmatter-markdown-loader. Разлог за ово је што је тај пакет за Nuxt прилагођен ситуацији у којој се серверски део апликације заиста извршава на Node.js серверу и само шаље донекле или делимично обрађен садржај клијентском делу. Уколико хостујемо сајт на статичком серверу, каква је већина (јефтиних) хостинг понуда код домаћих провајдера, користићемо SSG, тј. статички генерисан сајт. Ово не оставља места за додавање и уређивање чланака „у лету“, преко интерфејса саме апликације, па сам одлучио да директно искористим markdown-it.

Пре свега, направио сам фајл markdown-it.js са следећим садржајем:

import markdownIt from 'markdown-it';
import markdownItAbbr from 'markdown-it-abbr';
//...

var md = new markdownIt({html: true})
    .use(markdownItAbbr)
    //...
    ;

//...

export { md };

а затим и фајл plugins/markdown-it.js:

import { md } from '../markdown-it';

export default({ app }, inject) =>
{
    inject('mdRender', markdown => md.render(markdown));
};

Тиме се функција render() убацује у Nuxt-ов context и Vue инстанцу, па може да јој се приступи преко context.app.$mdRender() или this.$mdRender(). Сада једноставно могу да у оквиру компоненте странице напишем:

<template lang="pug">
    static-markdown(:markdown="markdown")
</template>

<script>
import StaticMarkdown from '~/components/StaticMarkdown';
export default {
    name: 'Koord',
    components: { StaticMarkdown },
    data()
    {
        return {
            markdown: '',
        };
    },
    async asyncData({ store, app })
    {
        let linkId = 'koord';
        await store.dispatch('articles/loadArticle', { linkId },
                             { root: true });
        let article = store.getters['articles/article'];
        return {
            markdown: article && article.markdown
                ? app.$mdRender(article.markdown)
                : ''
        };
    }
};
</script>

и Markdown ће бити преведен у HTML, у време генерисања страница, што омогућава видљивост претраживачима. Истовремено, постоји могућност накнадне хидрације подацима из базе. Планирам да овакву комбинацију евентуално применим и на чланке овог блога.

Локални PHP API и JWT, први део

Категорије:
  • ажурирања сајта

Кад желимо да направимо веб апликацију која треба да има могућност измене података, једно од првих питања на које треба одговорити је како ће бити решена веза између фронтенда, који је видљив корисницима, и бекенда, који чини погон апликације. Временом су се усталили стандарди за размену података, као што је AJAX, и формати представљања података, као што је JSON. Следеће питање које се намеће је како контролисати права приступа и измене података. Ако додамо могућност измене чланака или других елемената наше апликације, није згодно да та могућност буде доступна свима. Данас је један од најраспрострањенијих начина ауторизовања JSON Web Token, или скраћено JWT. Он функционише по принципу јавног и тајног кључа. Подаци који нам могу послужити за идентификацију чине JWT; они се потписују тајним кључем, кодирају уз помоћ Base64 и шаљу клијенту. Када клијент жели да приступи заштићеном ресурсу, уз захтев пошаље и JWT, који се декодира и провери дешифровањем потписа јавним кључем. Само јавни кључ који одговара тајном кључу којим је шифрован JWT ће верификовати податке. JWT се састоји од три дела: заглавља (header), главног дела (payload) и потписа (signature), који се после Base64 кодирања раздвајају тачкама.

Рецимо, за токен:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2dvb2dsZS5jb20iLCJhdWQiOiJodHRwczovL2dvb2dsZS5jb20iLCJuYW1lIjoi0J_QtdGC0LDRgCDQn9C10YLRgNC-0LLQuNGbIiwidXNlcm5hbWUiOiJwZXRlcnBhbjEyMzQ1IiwiYWRtaW4iOmZhbHNlLCJpYXQiOjE1ODY1NDE2NjEsImV4cCI6MTU4NjU0NzU2NSwianRpIjoiYTU3MWQ0NWItMTdmNy00N2I3LWJjM2ItZWRhMzFkN2IyNmIzIn0.Hb4Z6bsFFY2k-tshcCtQBOt768MAH0jmYWrnHshfaeM

Paste-овањем на сајту jsonwebtoken.io између осталог добијамо дешифрован JSON, који представља главни део, payload, JWT-а:

{
 "iss": "https://google.com",
 "aud": "https://google.com",
 "name": "Петар Петровић",
 "username": "peterpan12345",
 "admin": false,
 "iat": 1586541661,
 "exp": 1586545925,
 "jti": "a571d45b-17f7-47b7-bc3b-eda31d7b26b3"
}

Сва поља су потпуно опциона, али су нека од њих ипак стандардизована у стандарду RFC 7519. На пример, iat (Issued At) поље садржи Уникс timestamp времена креирања JWT-а, а iss (Issuer) ентитет који је креирао JWT.

Уколико се информације садржане у JWT-у тако лако декодирају, с правом се поставља питање безбедности JWT-а. Управо то је разлог тога да се не препоручује смештање осетљивих података као што су лозинке у payload. JWT служи само да успостави неку тврдњу, рецимо да је вредност параметра name ниска Петар Петровић. Тачност тврдње се проверава дешифровањем потписа јавним кључем.

Додавање тамне теме

Категорије:
  • ажурирања сајта

Најновија ставка коју сам додао мом сајту док радим на подршци за пријављивање преко друштвених мрежа је подршка за тамну тему прилагођену смерницама материјалног дизајна. То се у Vuetify-у изводи релативно једноставно; најтеже је одабрати саме боје тамне палете.

Када се дефинишу боје, потребно је проследити тему Vuetify-у. Ја сам се одлучио да тему поставим у два засебна фајла, који се затим учитавају преко директиве import.

Од Vim-а до IDE-а

Категорије:
  • програмирање

Једно од питања које ми други програмери поставе кад чују да се бавим програмирањем је које интегрисано окружење користим за развој апликација. По правилу се изненаде кад уместо очекиваних одговора као што су VS Code, JetBrains Web Storm или NetBeans, чују да користим Vim. Овај програм је током година доста напредовао у односу на своју инспирацију, програм vi, тако да данас сасвим комотно може да парира горенаведеним окружењима, или их чак и престигне.

Чуђење вероватно потиче од нетривијалног начина задавања чак и најосновнијих операција: рецимо, vi се, за разлику од велике већине других уређивача, подразумевано налази у „командном режиму“, па га није могуће само покренути и одмах почети са уношењем текста, већ се мора претходно пребацити у режим уноса пречицом i. Међутим, кад се једном „уђе у штос“, могуће су прилично напредне операције, које се све активирају са неколико тастера, рецимо ddp у командном режиму мења редослед два реда текста, а cw брише знаке до краја речи и пребацује се у insert mode, па тако можете заменити реч. Наредба за замену текста у читавом пасусу је само незнатно компликованија: vipc. Програмерима је изузетно корисно пребацивање између отворене и затворене заграде у пару тастером % или селекција свега између витичастих заграда комбинацијом vi}.

Ја константно допуњавам моја подешавања Vim-а, па ћу укратко написати и о томе.

Инсталација

Пре свега, програм који користим за развој апликација се тачније зове Neovim, и још прецизније, користим његову варијанту neovim-qt. Ради се о програму који је написан „од нуле“, уз задржану компатибилност са Vim-ом (а и он сам, VimVi IMproved, је побољшана верзија програма vi). Њега можете инсталирати пратећи упутства са neovim.io. Ипак, јасноће ради, овде ћу наставити да га зовем Vim.

Додаци

Иако је Vim сам по себи веома моћан, прави разлог тога што се може поредити са интегрисаним окружењима су додаци. Само неки од додатака које користим су:

  • Vim-CtrlSpace, додатак за управљање радним окружењем и чување сесија.

  • ALE, додатак за проверу и исправљање синтаксе.

  • Coc, IntelliSense додатак за Vim.

  • vim-airline, додатак за улепшано приказивање напредних информација у вези са фајлом који се уређује.

  • vimcolors/phosphor.vim, тема за Vim која подсећа на старе текстуалне терминале или боје кода у филму „Matrix“.

Фајл са подешавањима Vim-а који користим одржавам у репозиторијуму Strahinja/dotfiles.

Фонт

Можда није толико очито, али и избор фонта је битан. Мени се од постојећих опција највише свиђа фонт PxPlus IBM VGA са сајта int10h.org, коме сам додао симболе уз помоћ Nerd Fonts patcher-а. Резултат је следећи:

Снимак екрана програма Vim