Giter VIP home page Giter VIP logo

vision's People

Contributors

arb avatar bricss avatar bryant1410 avatar cjihrig avatar coderjonny avatar csakis avatar damusix avatar danielb2 avatar devinivy avatar fhemberger avatar hiddenboox avatar hueniverse avatar jagoda avatar jameswragg avatar jarrodyellets avatar johnbrett avatar jsteunou avatar keithamus avatar lallenfrancisl avatar lloydbenson avatar marsup avatar msj121 avatar nargonath avatar paulovieira avatar sholladay avatar simon-p-r avatar simonschick avatar sonicdoe avatar woutrbe avatar wswoodruff avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vision's Issues

Include global handlebars layout for use in plugin

I have an app using handlebars as the template engine and I want to register a series of plugins (user registration / auth) that render within the root apps handlebars layout. The plugin will only serve the user form.

Trying to serve a layout from the parent app throws this error:
[error] message: View paths cannot lookup templates outside root path (path includes one or more '../') stack: Error: View paths cannot lookup templates outside root path (path includes one or more '../')

In this case I am trying to pass the path of the root applications layout file via the plugin options.

How can I serve a handlebars template with a form via a hapi plugin but have it render within the root applications layout?

Global View Context

It would be nice if you could specify a global context value that would be merged into the passed in view context. Ideally it would take an object or a function in case you needed to do some logic while setting up your global context.

Currently, the only way to set up a global context is via an extension point and checking the response type for view.


server.views({
  context: {
    version: '1.5.5',
    name: 'Application Name',
  }
});
//OR
server.views({
  context: function (request) {
    return {
      version: '1.4.5',
      date: Date.now(),
      id: request.id
    }
  }
});

The value of server.views.context would be merged with whatever context gets passed into reply.view. Any collision, the local one overwrites the gloabal context


reply.view('index', {
  test: 'This is the index view'
});

Would result in a context object of

{
  version: '1.5.5',
  name: 'Application Name',
  test: 'This is the index view'
}
//OR
{
  version: '1.4.5',
  date: <timewhencontextruns>,
  id: 5,
  test: 'This is the index view'
}

I think this is much clearer than the suggested approach in the tutorials that looks like this:

// Server extension points
server.ext('onPreResponse', function (request, reply) {

  if (request.response.variety === 'view') {
      request.response.source.context = Hoek.applyToDefaults(server.settings.app.globalContext, request.response.source.context || {});
      reply();
  }
  else {
      reply();
  }
});

lint errors with vision

lib/index.js:
Line 103: hapi/hapi-for-you - Only one variable can be initialized per loop.
/lib/manager.js:
Line 421: hapi/hapi-for-you - Only one variable can be initialized per loop.
Line 453: hapi/hapi-for-you - Only one variable can be initialized per loop.

Send helper parsing error to user

If you include a helper in the helpers directory and it cannot be loaded (i.e. require() throws), the error is lost. It would be useful to see some kind of error here, perhaps you just made a simple syntax error that needs fixing.

dust.js - vision always wants to load a view from a folder

I have an application where some of my views are in plugins in a different and undetermined folders. I have a build process in gulp which compiles and combines all view into a single file. This file is loaded when the hapi server starts:

var dustViews = require("fs").readFileSync("./lib/views.min.js");
dust.loadSource(dustViews);
console.log('Views loaded to cache');

I have the following view setup for vision:

server.views({
    defaultExtension: "dust",
    engines: {
        dust: require('hapi-dust')
    },
    isCached: true
    //path: '../src/view',
    //relativeTo: __dirname,
    //compileMode: 'async'
});

Originally I had to specify the path but it should work without it as I already loaded all possible dust files into the cache. Why vision still insist on looking up the view in the folder? (and failing of course because the views collected from the plugins are not there - but they are in the dust cache!

Nested Layouts

Is it possible to have nested layouts? For example, there would be a "master" layout that contains site-wide HTML (e.g. - global header, etc.) and a section-specific layout that contains HTML shared within a certain section of the site.

An arbitrary example would be a "user settings" layout. The settings layout would contain common elements shared between each settings page, such as a menu for the settings sections. Would it be possible to render a specific settings page, such as "profile settings", into a settings layout that would then render into the master layout?

Q: Are template files cached?

Hey guys,

I have a plugin which uses handlebars as view engine.

    plugin.views({
      engines: {
        html: require('handlebars')
      },
      path: __dirname
    });

When I make changes to the login.html file I need to restart the server in order to force hapi to pick my changes.

I have globally registered Vision for my server and this is my route:

    plugin.route({
      method: 'GET',
      path: '/login',
      handler: (req, reply) => {
        reply.view('login', { title: 'Login page via handlebars' });
      },
      config: {
        auth: false
      }
    });

Is there a way to disable this while developing?

Partials not relative when overriding relativeTo in server.view options

When overriding relativeTo in the view options, the layout's are relative but the partials are not.

// server config
server.views({
    engines: {
        html: require('handlebars')
    },
    relativeTo: 'src/server',
    layout: 'default',
    layoutPath: 'layouts',
    partialsPath: 'partials'
});

// handler
var options = {
    relativeTo: 'view/base'
};
return reply.view('index', {}, options);

In the above configuration, the view engine correctly looks in the following location for a template named index.html.

src/server/view/base

It also correctly looks for a layout file named default in the following path

src/server/view/base/layouts

However, due to the way partials are loaded up front, the path for partials is relative to the engine path, as in the following:

src/server/partials

When the expected relative path for partials for this view should be

src/server/view/base/partials

Looking through the code it looks like optimization/pre loading was done with the partials which makes this difficult to change.

Need to know or control the order or priority of helper blocks.

Using hapi, vision and handlebars I want to created helpers to do jade style code blocks. In a partial or page I want to define a block of code to be placed in the head of the layout.. not in the {{{content}}} section of the layout.

Example template:

 <html> 
  <head> {{#myBlock}}{{/myBlock}} </head> 
  <body> {{{content}}} </body>
 </html> 

and in pages and partials I have this

 <div>My body content</div> 
{{#extendTo "css"}} 
    <!--some css style I want in the head --> 
    <style> div: { color: red; } </style> 
{{/extendTo}} 

My helper for #extendTo stores the style text and returns empty string. The helper for myBlock takes the stored value and returns it, making it appear in the head.

This works some of the time, but the problem is that the helper blocks are processed in an unknown order. In my example the #myBlock in the template is sometimes processed first. Then the the #extendTo blocks in pages / partials are processed. This means that the style does not make it into the page.

The hapi people told me that the pages / partials are all processed to strings before they are put into the layout and suggested that the priority or order might be in vision.

Is there any way to specify a priority for helper blocks? If a priority could be set I could make sure my extendTo blocks are processed first, guaranteeing that the content is in memory before any of the myBlock helper blocks are processed.

It almost seems like helpers should be processed on partials first, then pages, then layouts. Any way to enforce this?

Thanks.

same name partials in different folder being override

Hi all bro,
my code is:

var  backendPlugin = {
    register: function (server, options, next) {
        // register view template engine
        server.views({
            engines: {
                html: Handlebars,
            },

            //relativeTo: './views/backend',
            path: 'views/backend/templates',
            layoutPath: 'views/backend/layout',
            layout: 'default',
            partialsPath:'views/backend/partials',
            helpersPath: 'views/backend/helpers'
        });
        // add backend-only route
        server.route(Routes.backend);

        next();
    }
};

backendPlugin.register.attributes = {
    name: 'backendPlugin',
    version: '1.0.0'
};

var frontendPlugin = {
    register: function (server, options, next) {
        // register view template engine
        server.views({
            engines: {
                html: Handlebars,
            },
            //relativeTo: './views/frontend',
            path: 'views/frontend/templates',
            layoutPath: 'views/frontend/layout',
            layout: 'default',
            partialsPath:'views/frontend/partials',
            helpersPath: 'views/frontend/helpers'
        });
        // add frontend-only route
        server.route(Routes.frontend);

        next();
    }
};

and in layout of backend & layout of frontend : i insert partial footer

{{!< layout/default}}
{{! The tag above means - insert everything in this file into the {content} of the default.html template }}
{{> navbar}}
{{> content}}
{{> footer}}

but backend render footer is being override by footer of frontend. (html code display)

struct folder is:

projectfolder 
 --views
   ---backend
     ----partials
       -----footer.html
   ---frontend
     ----partials
       -----footer.html

.How extractly partials path to fix issue.

Jade problems / hanging

When i visit localhost:3000 template shows up but then if i change template and hit refresh, template shows up without changes, but process hangs for some time (depends how many times i hit refresh). Using same version of jade in express works.

Even if i copy sample from vision/examples/jade/index.js it is same ....

Did i miss something?

I have the following setup:

const Hapi = require('hapi');
const Hoek = require('hoek');
const jade = require('jade');
const vision = require('vision');
const server = new Hapi.Server();

server.connection({
  host: 'localhost', 
  port: 3000
});

  server.register(vision, (err) => {
    // Hoek.assert(!err, err);

    server.views({
      engines: {
        jade: jade
      },
      relativeTo: __dirname,
      path: 'views',
      compileOptions: {
        cache: true,
        pretty: false,
        debug: true,
        compileDebug: true
      }
    });
  });

  server.route({
    method: 'GET',
    path: '/sl',
    config: {
      id: 'root.sl',
      handler: function (request, reply) {
        reply.view('services');
      }
    }
  });

  // Start the server
  server.start((err) => {
    if (err) {
      throw err;
    }
    console.log('Server running at:', server.info.uri);
  });

Vision version: 4.0.1
Hapi version: 11.1.4
Jade version: 1.11.0
Node version: v5.3.0

ejs template engine options is not working

Hello, I pass a property compileOptions as following, but the ejs template always cache compile result, it's worng way?

server.views({
        engines: {
            ejs: require('ejs')
        },
        relativeTo: __dirname,
        path: 'Templates',
        compileOptions: {
            cache: false
        }
});

TypeError: Cannot read property '_render' of undefined

While trying to use [email protected] I receive this error when hitting the /documentation endpoint:

11:14:20 web.1  |     TypeError: Cannot read property '_render' of undefined
11:14:20 web.1  |     at Object.internals.marshal (...\node_modules\vision\lib\manager.js:583:12)
11:14:20 web.1  |     at internals.Response._marshal (...\node_modules\hapi\lib\response.js:473:22)
11:14:20 web.1  |     at internals.state (...\node_modules\hapi\lib\transmit.js:124:18)
11:14:20 web.1  |     at Items.parallel (...\node_modules\hapi\lib\transmit.js:509:20)
11:14:20 web.1  |     at done (...\node_modules\hapi\node_modules\items\lib\index.js:63:25)
11:14:20 web.1  |     at each (...\node_modules\hapi\lib\transmit.js:480:20)
11:14:20 web.1  |     at Object.exports.parallel (...\node_modules\hapi\node_modules\items\lib\index.js:70:13)
11:14:20 web.1  |     at Object.internals.state (...\node_modules\hapi\lib\transmit.js:502:11)
11:14:20 web.1  |     at Object.internals.marshal (...\node_modules\hapi\lib\transmit.js:98:15)
11:14:20 web.1  |     at Object.exports.send (...\node_modules\hapi\lib\transmit.js:30:15)

Diving in a bit, I see that manager._render is failing. The manager object looks like this:

{ statusCode: 200,
  data:
   { manager: { _context: null, _engines: [Object], _defaultExtension: 'html' },
     template: 'index.html',
     context: { hapiSwagger: [Object] },
     options: undefined,
     compiled: { settings: [Object], template: [Function] } } }

I'm new to vision, so I'm not sure what is causing this issue but figured I'd post here in case it is a bug.

Let me know if you need any further information.

Server decoration already defined: views

I am having a bit of an issue using vision with handlebars and hapi 9.*. I might be missing something, so below is my entire app.js. My error is this:

Server decoration already defined: views

What am I doing wrong?

var Hapi = require("hapi");
var path = require("path");
var vision = require("vision");
var inert = require("inert");
var jwt = require("jsonwebtoken");
var config = require("config");
var env = process.env.NODE_ENV || "development";
var user = require("./models/user");
var routes = require("./routes");
var validate = function (decodedToken, callback) {
  user.findById(decodedToken.accountKey, function(error, result) {
    if (!result) {
      return callback(error, false, result);
    }
    return callback(error, true, result)
  });
};

var server = new Hapi.Server({
  connections: {
    routes: {
      cors: true
    }
  }
});

server.register(vision, function (error) {
  if (error) {
    console.log("Failed to load vision.");
  }

  server.views({
    engines: {
      html: require("handlebars")
    },
    layout: true,
    path: __dirname,
    layoutPath: path.join(__dirname, "public/templates/core"),
    partialsPath: path.join(__dirname, "public/templates/core")
  });
});

server.connection({
  host: config.get("app.host"),
  port: config.get("app.port")
});

server.register({
  register: require("hapi-mongo-models"),
  options: {
    mongodb: {
      url: config.get("mongodb.url"),
      settings: {}
    },
    autoIndex: false
  }
}, function (error) {
  if (error) {
    console.log("Failed loading hapi-mongo-models plugin");
  }
});

server.register({
  register: require("yar"),
  options: {
    cookieOptions: {
      password: config.get("cookies.password"),
      isSecure: env === "development" ? false : true,
      isHttpOnly: true
    }
  }
}, function (error) {
  if (error) {
    console.log("Failed loading yar plugin");
  }
});

server.register({
  register: require("hapi-auth-jwt")
}, function (error) {
  if (error) {
    console.log("Failed loading hapi-auth-jwt plugin");
  }
  server.auth.strategy("token", "jwt", {
    key: config.get("auth.privateKey"),
    validateFunc: validate
  });
  server.route(routes);
});

server.app.config = config;

if (!module.parent) {
  server.register(require("blipp"), function(error) {
    if (error) {
      console.log("Failed loading blipp plugin");
    }
    server.register([
      inert,
      vision,
      {
        register: require("hapi-swagger"),
        options: {
          documentationPath: "/api/documentation"
        }
      }], function (error) {
      if (error) {
        console.log("Failed loading hapi-swagger plugin");
      }
      server.start(function() {
        // Add any server.route() config here
        console.log("Server running at:", server.info.uri);
      });
    });
  });
}

module.exports = server;

Cannot Load Partials

On Hapi 7.5.2, Vision 1.2.2, Handlebars 2.0.0 - I'm receiving the following error:

internalError, message: The partial header could not be found: The partial header could not be found stack: Error: The partial header could not be found

It was working, but what's changed, is that I've moved my configuration file up a level, which is set as follows:

settings: {
    views: {
      engines: {
        hbs: require('handlebars')
      },
      basePath: Path.join(__dirname, '../web'),
      path: './views',
      layoutPath: './views/layouts',
      helpersPath: './views/helpers',
      partialsPath: './views/partials',
      layout: true,
      isCached: false,
      allowAbsolutePaths: true,
      allowInsecureAccess: true
    }
}

Which is then loaded by a plugin as follows:

plugin.views(config.settings.views);

(The configuration object was previously loaded directory into the plugin.views method inside index.js for the plugin which was working fine).

I'm looking at vision source now (1.2.2), trying to see why partials may not be loading.

Issue with underscore partials and vision

Getting


Debug: internal, implementation, error 
    Error: settings.layoutKeyword conflict
...

with

module.exports = function(templ, options) {

  return function(ctx, options) {
    return require('underscore').template(templ)(ctx || null);
  };

};

module.exports = {
    engines: {
      'html': {
        compile: require('./underscore_compiler')
      }
    },
    compileMode: 'sync',
    path: __dirname + '/../../views',
    partialsPath: __dirname + '/../../views/partials'
};



it breaks when it tries to load the partial

similar code found here
molekilla/rutha@05c7b86

any idea ?

thanks

Vision loading all files in the helper's directory

This causes warnings to be logged to stdout. Could we change this to load only specific files?

Atm, if we have js.map files or tests or something else in that same folder, it will spit out warnings every app start.

Working with Swag

I previously used Swag(https://github.com/elving/swag) with hapi 7.5.3. I am having a hard time pin pointing the exact line of code that is causing a problem but the helper functions are no longer being registered.

I previously did:

var Handlebars        = require('handlebars');
var Swag              = require('swag');

Swag.registerHelpers(Handlebars);

server.views({
  engines: {
    hbs: Handlebars
  },
  path: './app/views',
  layoutPath: './app/views/layouts',
  layout: 'defaultLayout',
  partialsPath: './app/views'
});

and it worked. Now this seems to be broken with hapi 8. What is the proper way to load in helpers that are from another library

Register Helpers programmatically

Would be lovely if we could register helpers programmatically.

E.g. server.views.registerHelper('someHelper', function(){});

This would allow for simpler helper module sharing, rather than having to create a helper file for each helper in a bundle.

Perhaps this exists I just couldn't find a simple solution by reverse engineering.

Add request.render() support

The server.render() method does not work when used inside a request handler via request.server.render() when the view manager was created by a plugin. This is breaks because the request.server does not have access to the plugin realm where the view manager is configured (only has access to a view manager setup directly on the server root outside of any plugin).

The request.render() method works exactly the same way but it gets its realm from the route the request was bound to instead of the global server root.

Note that this will not work in onRequest extensions added by the plugin because the route isn't yet set at this point in the request lifecycle and the request.render() method will produce the same limited results server.render() can. If you need to call render() within onRequest, save a reference to the views manager direction from server.realm.plugins.vision.manager within the plugin and use that in the extension method.

modifying the views object before compilation

Prior to v3.0.0 we could modify the views object during the preResponse event. Moving the compilation step earlier in the request lifecycle no longer allows this. Any ideas on getting this work in v3.0.0?

Example:

template files:

./server/views/desktop/index.ejs
./server/views/mobile/index.ejs

views object:

views: {
    engines: {
        'ejs': ejs
    },
    relativeTo: './server/views'
};

onPreResponse:

if ( response.variety === 'view' ) {
    var userAgent = request.plugins.scooter;

    if ( mobileIdentifier( userAgent ) ) {
        request.response.source.options = { path: 'mobile' };
    } else {
        request.response.source.options = { path: 'desktop' };
   }
};

Vision 2.0.1 installing joi 5.1.0 instead of 6.x.x

I have a couple of apps that when I deploy to a server, hapi 8.8.0 is installed which has vision 2.x.x as a dependency and installs vision 2.0.1. Vision 2.0.1 has joi 6.x.x as a dependency, but it installs joi 5.1.0.

How is this possible? I have 2 different apps on 2 different computers which deploy to 2 different servers which completely different setups.

Vision Registration Failing?

Hi there - upgrading to hapi v9.0.0, and have added the vision dependency, as well as what I thought was the correct require statement during plugin registration, but the application is failing with:

server/web/index.js:53
    server.views({
           ^
TypeError: undefined is not a function

Here's a Gist to the complete application setup...

https://gist.github.com/58bits/12e3a8380327062a762b

Is there anything obvious wrong here?

@hueniverse any ideas?

Global context with request argument

When global context was first suggested in #4, functions that generate context could have a request argument. Like this :

server.views({
  context: function (request) {
    return {
      version: '1.4.5',
      date: Date.now(),
      id: request.id
    }
  }
});

But it is not actually implemented now, and I think that idea is quite essential in many cases of developments.

template error results in no boom

When compiled.template throws an Error it's handled via Hapi's fail function within transmit.js which causes a new Response to be generated. By the time that this new response is propagated to onPreResponse listeners there is no indication that an error has occurred via request.response.isBoom.

Hapi v13.0.0
Vision v4.0.1

404 gives error

Hi!

It looks like vision gives a error on 404 pages and just hangs the server. I will look into it later, but for now I just thought you should know. Maybe it is some easy error? Or is it related to the updates you are making on the hapi 8.0 release?

Debug: hapi, internal, implementation, error
    TypeError: Cannot read property 'hasOwnProperty' of undefined
    at /Users/Torsph/Development/node/aam/node_modules/hapi/node_modules/vision/lib/index.js:329:20
    at /Users/Torsph/Development/node/aam/node_modules/hapi/node_modules/vision/lib/index.js:432:20
    at Object.engine.compileFunc (/Users/Torsph/Development/node/aam/node_modules/hapi/node_modules/vision/lib/index.js:162:24)
    at /Users/Torsph/Development/node/aam/node_modules/hapi/node_modules/vision/lib/index.js:422:16
    at fs.js:291:14
    at Object.oncomplete (fs.js:97:15)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.