Spuštění vlastního RSS kanálu s Express a Jade

RSS kanály jsou skvělým způsobem, jak zajistit věrné čtenáře. Ve skutečnosti, když to píšu, RSS kanál v Davidově postranním panelu nabízí více než 11 400 odběratelů. Dostat se na titulní stránku Hacker News je vždy příjemné, ale pro většinu webů to nebude spolehlivý zdroj návštěvnosti. Dostat každý příspěvek před tisíce záměrných odběratelů (kteří mají své vlastní sledující na Twitteru, Google+ atd.)? To je generátor provozu.

RSS kanály mají opravdu jen jeden přístup – jeden musíte mít. Před více než měsícem jsem spustil nový blog DevSmash. Můj zbrusu nový web byl veřejný méně než 48 hodin, když jsem dostal tweet s dotazem, kde je můj RSS kanál. Ne pokud Měl jsem zdroj RSS, ale kde byl můj RSS kanál. Víte, měl jsem to štěstí, že jsem v jednom ze svých prvních příspěvků dostal nějakou slušnou propagaci. Uživatelé se začali objevovat a někteří z nich evidentně hledali nějaký způsob, jak se přihlásit. Nyní mám samozřejmě RSS kanál, ale všichni uživatelé, kteří se objevili během prvního týdne, jsou už dávno pryč. Morálka příběhu:RSS kanály jsou skvělé, ale potřebujete je před vaši čtenáři se objeví.

Dobře - říkejme tomu dostatečný kontext. DevSmash je postaven na všech nových dobrotách, které byste si mohli přát:Node.js, Express, Jade, Stylus, MongoDB, Mongoose atd. Je to stack, na kterém naprosto miluji hackování, ale odhaluje záměrně štíhlou sadu funkcí, takže „rolování vlastního xyz " často přichází s územím. To byl případ mého RSS kanálu. Tento příspěvek poskytuje přehled toho, jak jsem vytvořil RSS kanál DevSmash, a doufám, že bude užitečný pro ostatní, kteří budují na tomto stále oblíbenějším zásobníku.

Obsazení postav

Než začneme, pojďme si udělat rychlý přehled hlavních technologií, které budeme používat:

Expresní

Z domovské stránky Express:"Express je minimální a flexibilní rámec webových aplikací node.js, který poskytuje robustní sadu funkcí pro vytváření jednostránkových, vícestránkových a hybridních webových aplikací." TJ Holowaychuk je příliš skromný na to, aby zde řekl, že Express se stal de facto standardem pro vytváření webových aplikací na Node. Existují samozřejmě i další možnosti, ale pokud jste to ještě neudělali, určitě si to dlužíte sami.

Web: http://expressjs.com/

Jadeit

Z readme Jade:"Jade je vysoce výkonný šablonovací engine silně ovlivněný Hamlem a implementovaný pomocí JavaScriptu pro node." Toto je můj oblíbený nástroj šablon – stručný, bohatý na funkce a syntaxe, která se čte stejně dobře jako zapisuje.

Web: http://jade-lang.com/

Mungus

Z repozitáře Mongoose GitHub:"Mongoose je nástroj pro modelování objektů MongoDB navržený pro práci v asynchronním prostředí." Jinými slovy, Mongoose poskytuje modelovou vrstvu pro interakci s vašimi kolekcemi MongoDB z Node.

Web: http://mongoosejs.com/

Poznámka:Je relativně bezvýznamné, že v tomto příspěvku používáme Mongoose. Koncepty by se měly přeložit dostatečně dobře do toho, jak svou vytrvalost řídíte.

Požadavky RSS

Ještě poslední věc, než se pustíme do kódu – pojďme identifikovat naše základní požadavky na náš RSS zdroj:

  1. Zdroj by měl obsahovat posledních 20 publikovaných příspěvky.
  2. Výstup by měl být platný zdroj RSS 2.0 (osobně k ověření používám validátor zdroje W3C).

Dost jednoduché.

Kodex

V zájmu tohoto článku se musíme zabývat pouze třemi soubory:

  • blog-post.js : Náš model Mongoose BlogPost (podrobnosti o implementaci nejsou pro tento článek příliš důležité, ale pro úplnost jsou uvedeny).
  • feed.js : Náš obslužný program trasy (zodpovědný za načítání příspěvků z databáze a jejich poskytování do našeho zobrazení).
  • rss.jade : Naše šablona RSS (odpovědná za přeměnu našich příspěvků na platný zdroj RSS 2.0).

blog-post.js

Nebudeme trávit příliš mnoho času povídáním o tomto souboru – je zde čistě pro informaci, protože s ním budeme pracovat později.

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var BlogPostSchema = new Schema({
    title: { type: String, required: true, trim: true },
    slug: { type: String, required: true, lowercase: true, trim: true, index: { unique: true } },
    body: { type: String, required: true },
    teaser: { type: String, required: true },
    author: { type: String, required: true, trim: true },
    published: { type: Boolean, required: true, default: false },
    createdAt: { type: Number },
    updatedAt: { type: Number }
});

// update timestamps on save
BlogPostSchema.pre('save', function(next) {
    this.updatedAt = Date.now();
    if (this.isNew) this.createdAt = this.updatedAt;
    next();
});

// create and export our model
module.exports = mongoose.model('BlogPost', BlogPostSchema);

feed.js

Běžnou expresní konvencí pro obslužné rutiny směrování je umístit je do vyhrazeného routes/ složku. V mých vlastních aplikacích obvykle exportuji soubory směrování jedinou funkci, která přijímá instanci aplikace Express, například takto:

// some-route-handler.js
module.exports = function(app) {
    app.get('/some/path', function(req, res, next) {
        // handler logic
    });
};

Se strukturou kódu, jako je tato, vaše hlavní app.js soubor jednoduše potřebuje řádek jako je tento:

require('./routes/some-route-handler')(app);

Dobrá tedy, takto vypadá funkční obslužný program RSS:

var BlogPost = require('../lib/model/blog-post');
module.exports = function(app) {
    app.get('/feed/rss', function(req, res) {
        BlogPost.find({})
            .sort('-publishedAt')
            .where('published', true)
            .limit(20)
            .select('title slug publishedAt teaser')
            .exec(function(err, posts) {
                if (err) return next(err);
                return res.render('rss' {
                    posts: posts
                });
            });
    });
};

Jak je vidět, není potřeba se příliš šťourat kolem naplňování našeho RSS kanálu. Jednoduše se dotazujeme na posledních 20 publikovaných příspěvků a vykreslíme je pomocí naší šablony RSS. Což nás přivádí k...

rss.jade

Zatímco primárním případem použití Jade je generování výstupu HTML, je stejně užitečné při generování XML. Naše šablona Jade vypadá takto:

doctype xml
rss(version='2.0', xmlns:atom='<a href="http://www.w3.org/2005/Atom" rel="nofollow">http://www.w3.org/2005/Atom</a>')
    channel
        title DevSmash
        link <a href="http://devsmash.com" rel="nofollow">http://devsmash.com</a>
        atom:link(href='<a href="http://devsmash.com/feed/rss" rel="nofollow">http://devsmash.com/feed/rss</a>', rel='self', type='application/rss+xml')
        description Developers talking about stuff that developers like to talk about.
        language en-US
        if posts.length
            lastBuildDate= new Date(posts[0].publishedAt).toUTCString()
        each post in posts
            item
                title= post.title
                link <a href="http://devsmash.com/blog/#{post.slug}" rel="nofollow">http://devsmash.com/blog/#{post.slug}</a>
                description
                    | <![CDATA[
                    | !{post.teaser}
                    p: a(href='<a href="http://devsmash.com/blog/#{post.slug}')!=" rel="nofollow">http://devsmash.com/blog/#{post.slug}')!=</a> 'Read more &raquo;'
                    | ]]>
                pubDate= new Date(post.publishedAt).toUTCString()
                guid(isPermaLink='false') <a href="http://devsmash.com/blog/#{post.slug}" rel="nofollow">http://devsmash.com/blog/#{post.slug}</a>

Syntaxe Jade může vypadat trochu cize, pokud ji vidíte poprvé, ale z velké části jsou věci docela samozřejmé. Je tu však několik věcí, které stojí za zmínku:

  • atom věci nejsou striktně vyžadovány, ale byly navrženy validátorem zdroje W3C.
  • Vydání těla příspěvku (nebo v tomto případě upoutávky) vyžaduje zvláštní péči. Nemůžete kódovat značky, nebo jednoduše uvidíte kódovaný HTML ve čtečce RSS, ale zároveň musíme chránit XML. Standardním řešením je tedy zabalit označení příspěvku do CDATA značky.

A tady to máte! Ani ne 40 řádků kódu (nepočítám model) pro vlastní RSS zdroj. Doufám, že to bylo užitečné, a rád bych slyšel jakékoli myšlenky, otázky nebo obavy v komentářích!