48

ExpressFrameworkを使用してNode.jsでCMSを作成しています。私のCMSには、ユーザーやページなどのためのいくつかのモジュールがあります。

各モジュールのファイルを、ビューファイルを含む別々のフォルダーに配置する必要があります。どうすればそれを達成できるか知っている人はいますか?

テンプレートエンジンとしてswigを使用していますが、役立つ場合は別のものに置き換えることができます。

4

5 に答える 5

51

最後の更新

複数のビュー フォルダー機能は、Express 4.10 以降のフレームワークでサポートされています。

viewsこのように、場所の配列をプロパティに渡すだけです。

app.set('views', [__dirname + '/viewsFolder1', __dirname + '/viewsFolder2']);

エクスプレス 2.0

私が知る限り、Express は現時点で複数のビュー パスまたは名前空間をサポートしていません (静的ミドルウェアのように)。

ただし、ルックアップ ロジックを自分で変更して、希望どおりに動作するようにすることもできます。次に例を示します。

function enableMultipleViewFolders(express) {
    // proxy function to the default view lookup
    var lookupProxy = express.view.lookup;

    express.view.lookup = function (view, options) {
        if (options.root instanceof Array) {
            // clones the options object
            var opts = {};
            for (var key in options) opts[key] = options[key];

            // loops through the paths and tries to match the view
            var matchedView = null,
                roots = opts.root;
            for (var i=0; i<roots.length; i++) {
                opts.root = roots[i];
                matchedView = lookupProxy.call(this, view, opts);
                if (matchedView.exists) break;
            }
            return matchedView;
        }

        return lookupProxy.call(express.view, view, options)
    };
}

上記の関数を呼び出してパラメーターとしてexpressを渡すことで新しいロジックを有効にすると、構成にビューの配列を指定できるようになります。

var express = require('express');
enableMultipleViewFolders(express);
app.set('views', [__dirname + '/viewsFolder1', __dirname + '/viewsFolder2']);

または、必要に応じて、フレームワークに直接パッチを適用することもできます (その中のview.jsファイルを更新します) 。

これはExpress 2.xで動作するはずですが、新しいバージョン (3.x) で動作するかどうかは不明です

アップデート

残念ながら、 express.view定義されていないため、上記のソリューションは Express 3.x では機能しません。

別の可能な解決策は、response.render関数をプロキシし、一致するまでビューフォルダー構成を設定することです。

var renderProxy = express.response.render;
express.render = function(){
    app.set('views', 'path/to/custom/views');
    try {
        return renderProxy.apply(this, arguments);
    }
    catch (e) {}
    app.set('views', 'path/to/default/views');       
    return renderProxy.apply(this, arguments);
};

私はそれをテストしていませんが、とにかく私には非常にハッキリしているように感じます。残念ながら、この機能は再びプッシュバックされました: https://github.com/visionmedia/express/pull/1186

更新 2

次のプル リクエストがマージされたため、この機能は Express 4.10 に追加されました: https://github.com/strongloop/express/pull/2320

于 2012-07-04T09:17:31.710 に答える
5

Express 3.x のソリューションは次のとおりです。上記の@ShadowCloudのソリューションと同じルックアップトリックを実行するために、express 3.xの「ビュー」オブジェクトにモンキーパッチを適用します。View残念ながら、 3.x では公開されていないため、オブジェクトのパス ルックアップはあまりクリーンではありませんexpress。そのため、node_modules の奥深くまで掘り下げる必要があります。

function enable_multiple_view_folders() {
    // Monkey-patch express to accept multiple paths for looking up views.
    // this path may change depending on your setup.
    var View = require("./node_modules/express/lib/view"),
        lookup_proxy = View.prototype.lookup;

    View.prototype.lookup = function(viewName) {
        var context, match;
        if (this.root instanceof Array) {
            for (var i = 0; i < this.root.length; i++) {
                context = {root: this.root[i]};
                match = lookup_proxy.call(context, viewName);
                if (match) {
                    return match;
                }
            }
            return null;
        }
        return lookup_proxy.call(this, viewName);
    };
}

enable_multiple_view_folders();
于 2013-03-08T22:05:02.497 に答える
0

グロブをインストールnpm install glob

views次のようなディレクトリがある場合:

views
├── 404.ejs
├── home.ejs
├── includes
│   ├── header.ejs
│   └── footer.ejs
├── post
│   ├── create.ejs
│   └── edit.ejs
└── profile.ejs

このグロブ関数を使用して、ディレクトリ内のサブディレクトリの配列を返すことができますviews(path.substring末尾の を削除するには、を追加します/) 。

let viewPaths = glob.sync('views/**/').map(path => {
    return path.substring(0, path.length - 1)
})


console.log(viewPaths)
>> ['views', 'views/post', 'views/includes']

だから今、あなたは設定することができます

app.set('views', viewPaths)

そして今、あなたは使用することができます

res.render('404')
res.render('home')
res.render('post/edit')
res.render('post/create')
于 2019-08-13T11:40:19.053 に答える