O projekcie

Analiza wymagań

Aplikacja (księgarnia) działa w dwóch trybach: „strona główna” (Rysunek 6.1) oraz „gatunek” (Rysunek 6.2). W trybie gatunek część adresu, mianowicie, path, jest nazwą gatunku.

Rysunek 6.1. Strona główna księgarni

Aplikacja w trybie „strona główna”

Rysunek 6.2. Księgarnia w trybie „gatunek”

Aplikacja w trybie „gatunek”

Aplikacja została zaimplementowana w oparciu o moduł express oraz maszynę szablonów ejs. Nie jest to jedyny sposób na tworzenie aplikacji internetowej w node.js

Struktura plików

Struktura plików aplikacji podana jest na poniższym obrazku.

.
├── db
│   └── books.js
├── Gruntfile.js
├── package.json
├── public
│   ├── css
│   │   └── styl.css
│   └── favicon.ico
├── serwer.js
└── views
    ├── index.ejs
    └── partials
        ├── footer.ejs
        ├── genre.ejs
        ├── header.ejs
        ├── main.ejs
        ├── nav_genres.ejs
        └── ul_genres.ejs

Na najwyższym poziomie znajdują się trzy pliki:

Gruntfile.js

W tym pliku określa się zadanie dla grunta. W szczególności, jakie pliki trzeba zarchiwizować do pliku zurek.zip.

package.js

W tym pliku określa się konfiguracja projektu. W szczególności, jakie moduły powinny zostać zainstalowane poleceniem npm install.

serwer.js

W tym pliku jest właściwie aplikacja serwerowa.

Pozostałe pliki umieszczone są w katalogach:

db

Tu znajduje się plik z bazą danych. Obsługa bazy danych została zaimplementowana za pomocą modułu taffy.

public

W tym katalogu są pliki, które zostaną wysłane do klienta bez zmian. Na przykład, plik styl.css.

views

W tym katalogu znajdują się szablony ejs. Szablony te zawierają znaczniki HTML oraz specjalne znaczniki, w których są zawarte wyrażenia w JavaScript, które zostaną obliczane podczas serwowania strony. Wartości zmiennych dla szablonu obliczane są w serwer.js. Szablon główny, index.ejs, został podzielony na części składowe, które są umieszczone w katalogu views/partials

Plik serwer.js

Na początku ładuje się moduły. Co robi moduł morgan? Zwróć uwagę, że moduł ./db/books z bazą danych nie jest standardowym. Zajrzyj do jego kodu.

/*jshint globalstrict: true, devel: true, node: true */
'use strict';

let express = require('express');
let app = express();
let path = require('path');
let bodyParser = require('body-parser');
let favicon = require('serve-favicon');
let morgan = require('morgan');
let baza = require('./db/books');

Ustawia się ejs jako maszynę szablonów

app.set('view engine', 'ejs');

Rejestruje się moduły do wykorzystania z expresem.

app.use(morgan('dev'));
app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static(path.join(__dirname, 'public')));

Rejestracja callbacków dla generowania odpowiedzi na żądania klienta. W trybie „strona główna” żądanie przychodzi metodą get na /. W trybie „gatunek” żądanie przychodzi metodą get na /:genre, przy czym genre staje się zmienna (zwróć uwagę na dwukropek). Metodą post przychodzą dane z formularza. Czemu tak się dzieję? Czy widzisz, w jaki sposób przekazywane są dane do szablonu?

app.get('/', function (req, res) {
    let genres = baza().distinct("genre");
    res.render('index.ejs', {genres: genres});
});

app.get('/:gen', function (req, res) {
    let genres = baza().distinct("genre");
    let books = baza({genre: req.params.gen}).select("title", "author");
    let genre = req.params.gen;
    res.render('index.ejs', {genres: genres, books: books, genre: genre});
});

app.post('/:gen', function (req, res) {
    let newAuthor=req.body.author;
    let newTitle=req.body.title;
    let genre = req.params.gen;
    console.log(newAuthor, newTitle);
    let genres = baza().distinct("genre");
    let books = baza({genre: genre}).select("title", "author");
    res.render('index.ejs', {genres: genres, books: books, genre: genre});
});

Uruchamia się serwer na porcie 3000.

app.listen(3000, function () {
    console.log('Serwer działa na porcie 3000');
});

Opracowanie zdarzenia SIGINT (CTRL+C na serwerze).

process.on('SIGINT',function(){
  console.log('\nshutting down');
  process.exit();
});

Szablon główny (index.js)

<%- include("partials/header.ejs") %>

<% if( typeof books == 'undefined') { %>
    <%- include("partials/main.ejs")%>
<% } else {%>
    <%- include("partials/genre.ejs")%>
<% } %>

<%- include("partials/header.ejs") %>

We wszystkich szablonach tryby pracy aplikacji rozróżniane są tak: w trybie „strona główna” zmienna books nie jest określona.