Rozlúčka s Pythonom III

Zápisník experimentátora

Musím sa ponáhľať s konverziou blogu, pretože Google na nás tlačí, aby sme prešli na novšiu verziu, alebo na nejaké úplne iné prostredie. Mne je najbližší javascript a NodeJS. V predchádzajúcich týždňoch som na projekte usilovne pracoval a niektoré časti blogu už mám hotové. Mám hotovú úvodnú stranu, zobrazenie blogu, zobrazenie stránky a index blogov. Všetko je síce ešt mierne nedorobené, ale plne funkčné.

Python

Povedal som si, že je načase, aby sme si ukázali, ako som mal urobený pôvodný blog. Toto je napríklad ukážka kódu, ktorý zabezpečoval generovanie konkrétnej stránky blogu.

class SingleArticleUrlBlogHandler(webapp2.RequestHandler):
    def get(self, year, month, path):
        template_values = {
            'caption': u'Arduino Slovakia',
            'description': u'Zápisník experimentátora',
            'path': self.request.path,
            'showadd': True
        }

        # nastavenie jazyka stranky
        lang = self.request.get('lang')
        if lang not in ['sk', 'cs', 'en']:
            lang = 'sk'

        a = Article.geturl_translated(year + "/" + month + "/" + path, lang)
        if a is None:
            self.response.set_status(404)
            self.response.write("404 Page Not Found!")
            return

        if a.has_parent:
            pl = parent.ParentList()
            a.parent_url = pl.translate_url(a.parent_name)
            a.parent_name = pl.translate_name(a.parent_name)

        template_values['bol_preklad'] = a.bol_preklad
        template_values['article'] = a
        template_values['caption'] = a.title
        template_values['render'] = 'article'
        template_values['lang'] = lang
        if lang == 'sk':
            template_values['canonical'] = '/blog/' + year + '/' + month + '/' + path
        else:
            template_values['canonical'] = '/blog/' + year + '/' + month + '/' + path + '?lang=' + lang
        funkcie.tlang = template_values['lang']
        template_values['languages'] = funkcie.get_languages(a.languages, self.request)
        template_values['menu'] = menu.get_menu(template_values['lang'])
        hidden = self.request.get('hidden')
        template_values['hidden'] = hidden
        if hidden == '1':
            template_values['showadd'] = False

        # ziskanie zoznamu suborov
        template_values['uploads'] = self.get_download(a.download)

        # upravenie menu
        template_values['menu'] = self.modify_menu(template_values['menu'], a)

        # YouTube
        if a.jason:
            data = json.loads(a.jason)
            if 'youtube' in data:
                yl = []
                y = data['youtube']
                # logging.info(y)
                if isinstance(y, list):
                    yl = y
                    # logging.info('list')
                if isinstance(y, basestring):
                    yl.append(y)
                if len(yl):
                    template_values['youtube'] = yl

        template = JINJA_ENVIRONMENT.get_template('blog.html')
        self.response.write(template.render(template_values))

Javascript

A toto je ukážka nového kódu, ktorý robí to isté. Nie je tam úplne všetko implementované a niektoré pôvodné vlastnosti blogu ani nebudem implementovať.

router.get(/\/blog\/(.+)/, async function (req, res, next) {
  let bl = new BlogLoader();
  let mn = new MenuLoader();

  try {
    let article = await bl.get(req.language, req.params[0]);
    let tpl = await bl.getView('blog.html');
    let ptpl = await bl.getViewPartials(tpl);
    let data = {
      title: article.title,
      description: 'Zápisník experimentátora',
      language: req.language,
      lang: bl.getLang(article),
      article: article,
      menu: await mn.get(req.language)
    };

    if (article.body.indexOf('</code>') != -1)
      data.highlighter = true;

    let r = mustache.render(tpl, data, ptpl, ['[[', ']]']);
    res.setHeader('Content-type', 'text/html');
    res.send(r);
  } catch (error) {
    console.error(error.message);
    res.status(400).json({ error: error.message });
  }
});

A ešte jedna ukážka kódu, ktorý zoberie z Datastore obsah pôvodného blogu a zabezpečí preklad a upraví obsah tak, aby bol kompatibilný s Bootstrap 5.

get(language, url) {
    return new Promise(async (resolve, reject) => {
      let query = this.datastore.createQuery('Article')
        .filter('url', url);

      try {
        let [q] = await this.datastore.runQuery(query);
        if (q.length == 0)
          reject(new Error(`Article '${language}.${url}'`));

        if (language != 'sk') {
          let queryt = this.datastore.createQuery('ArticleTranslation')
            .filter('language', language)
            .filter('active', true)
            .filter('page', q[0][this.datastore.KEY]);
          let [qt] = await this.datastore.runQuery(queryt);
          if (qt.length) {
            q[0].title = qt[0].title_translated;
            q[0].body = qt[0].body_translated;
            q[0].created_when = qt[0].created_when;
            q[0].modified_when = qt[0].modified_when;
            q[0].published_when = qt[0].modified_when;
          }
        }

        let s = q[0].body;
        s = s.replace(/center-block img-responsive/g, 'img-fluid rounded-3 shadow');
        s = s.replace(/width:640px/g, '');
        q[0].body = s;
        resolve(q[0]);

      } catch (error) {
        reject(error);
      }
    });
  }

Na vytvorenie obsahu používam šablónovací systém Mustache a vzorová šablóna v Mustache môže vyzerať napríklad takto.

<!DOCTYPE html>
<html lang="[[language]]">

<head>
  [[>header-head]]
</head>

<body>
  <div class="container">
    [[>header-body]]
    <div class="row">
      <div class="col-sm-9">
        [[&article.body]]
      </div>
      <div class="col-sm-3">
        <h3>Menu</h3>
        [[>menu]]
      </div>
    </div>

    [[>footer]]
  </div>
</body>

</html>

09.11.2021


Menu