Where to put a separate admin interface for a Mete

2020-06-12 03:27发布

问题:

I'm trying to build a smart package for Meteor app that provides some monitoring capabilities and other tools based on the features of the smart package. For more details read this question.

In any case, I'm trying to figure out the best way to create an admin interface for this package, which will of course be itself running in Meteor. Ideally, I'd like something similar to observatory, except on a separate part of the site that the package can control (or even on a different port.)

The way the observatory folks have tackled this problem is pretty ingenious - they just have a popup div on the main app page that provides the necessary information. That's fine, but not the optimal way for revealing the interface on an app, in my opinion. The problem with using routes is that the popular Meteor router that everyone uses doesn't support more than one "stack" of pages, and better Meteor routers that have been developed (such as by Chris Mather in Devshop 5) haven't been released yet.

Can anyone suggest a good approach to tackle this problem? Ideally my package would just be able to render its own admin templates on a separate part of the site such as /admin.

回答1:

As James Hatfield pointed out, Iron-Router now supports multiple layouts. For those hitting this thread now, this is the best way to handle the multiple layout scenario.

Router.map ->
  @route 'home',
    layoutTemplate: 'homeLayout'
    path: '/'

  @route 'dashboard',
    layoutTemplate: 'dashboardLayout'


回答2:

IronRouter supports multiple layouts.

https://github.com/EventedMind/iron-router

Router.configure({
  layout: 'layout',
  notFoundTemplate: 'notFound',

  loadingTemplate: 'loading',

  renderTemplates: { 
    /* render the templated named footer to the 'footer' yield */
    'footer': { to: 'footer' },

    /* render the template named sidebar to the 'sidebar' yield */
    'header': { to: 'header' }
  }
});

Router.map(function() { 

  this.route('admin', {
    layout: 'admin_layout',
    path: '/admin',
    template: 'admin',
    data: function() {
      return { page : 'admin'}
    },
    onBeforeRun: checkLoggedIn,
    renderTemplates: { 
    /* render the template named footer to the 'footer' yield */
    'admin_footer': {to: 'footer'},

    /* render the template named sidebar to the 'sidebar' yield */
    'admin_login_header': {to: 'header'}
    }
  });

this.route('home', {
    path: '/',
    template: 'home',
    data: function() {
      return { page : 'home'}
    }
  });


<template name="layout">
//this is where your standard view layout goes

</template>

<template name="admin_layout">
//this is where your admin view layout goes

</template>

Could work pretty well if you match it up with Meteor accounts UserID checks and onBeforeRun hooks. I haven't fully tested the security aspect but it looks like it will work.



回答3:

Please take a look at my project at github. I have a solution for this. It might not be the best, but it is working so far.

github.com/voteapp

<head>
    <title>Index</title>
</head>

<body>
    {{> root}}
</body>

root template is using some other templates inside. I may use 2 different index files. 1 for site and 1 for management panel.

root template:

<template name="root">
    {{#if adminURL}}
        {{> adminLogin}}
    {{else}}
        {{> site}}
    {{/if}}
</template>

adminLogin template:

<template name="adminLogin">
    {{#if currentUser}}
        {{> management}}
    {{else}}
        admin login page.
            <div style="float: right">
              {{loginButtons align="right"}}
            </div>
    {{/if}}
</template>

management template:

<template name="management">
    <div id="header" class="navbar">
       ....
    </div>
    <div id="container" class="row-fluid">
       ....
    </div>

    <link rel="stylesheet" href="/css/admin.css">
</template>

site template:

<template name="site">
     <h1>Hello World!</h1>

     <link rel="stylesheet" href="/css/site.css">
</template>

This is not actually html from my project but it is something like this. With this way, CSS links will appear at the end of body tag. And for admin panel and site itself will have different html structure and css files. Also you may want to add javasctipt files also.



回答4:

Hi & thanks for referencing observatory! You are completely right in that eventually it would be nice to have management & monitoring separately and in fact we've been working in that direction lately, and this is going to be a primary direction as well - the goal is to monitor, analyze logs and provide some management capabilities in the cloud. It already has some basic functionality - check it out here: http://vega.observatoryjs.com/demo

BTW, the way we handled your problem in original observatory - just create a separate route in Pages or Iron Router etc and put just the observatory (or your admin panel) template there - in our case {{>logs_bootstrap}}. This way it'll be completely separate from the main app. But cloud is even better :)



回答5:

Isn't this doable by simply using Meteor router and template helpers:

Specify your routes:

Meteor.Router.add({
    '/foo'  : 'foo',
    '/admin': 'admin'
});

Let's say you have a 3 column layout. Create your template like this:

<template name="body">
  <div class="container">
    <div class="span"4>
      {{renderPage LeftLayoutName}}
    </div>
    <div class="span"4>
      {{renderPage MiddleLayoutName}}
    </div>
    <div class="span"4>
      {{renderPage RightLayoutName}}
    </div>
  </div>      
</template>

Then specify your template helpers:

Template.body.helpers({
  LeftLayoutName: function() {
    switch (Meteor.Router.page()) {
      case 'foo':
        return 'foo_left';
      case 'admin':
        return 'admin_left';
    }
  },
  MiddleLayoutName: function() {
    switch (Meteor.Router.page()) {
      case 'foo':
        return 'foo_middle';
      case 'admin':
        return 'admin_middle';
    }
  },
  RightLayoutName: function() {
    switch (Meteor.Router.page()) {
      case 'foo':
        return 'foo_right';
      case 'admin':
        return 'admin_right';
    }
  }
});


回答6:

I had a similar question. There is less clunky example of doing this in the router meteor package example.

https://github.com/tmeasday/meteor-router/tree/master/examples/app-with-layout

Hope this helps.