Где разместить отдельный админ-интерфейс для приложения Meteor?

Я пытаюсь создать интеллектуальный пакет для приложения Meteor, который предоставляет некоторые возможности мониторинга и другие инструменты, основанные на особенностях интеллектуального пакета. Подробнее читайте этот вопрос.

В любом случае, я пытаюсь найти лучший способ создать интерфейс администратора для этого пакета, который, конечно же, будет работать в Meteor. В идеале мне бы хотелось что-то похожее на observatory, за исключением отдельной части сайта, которую пакет может контролировать (или даже на другой порт.)

То, как обсерватория решает эту проблему, довольно гениально - у них просто есть всплывающее окно на главной странице приложения, которое предоставляет необходимую информацию. Это прекрасный, но не оптимальный способ выявления интерфейса в приложении, на мой взгляд. Проблема с использованием маршрутов заключается в том, что популярный Meteor router, который каждый использует не поддерживает более одного "стека" страниц и лучших маршрутизаторов Meteor, которые были разработаны (например, Chris Mather в Devshop 5) еще не выпущены.

Можно ли предложить хороший подход к решению этой проблемы? В идеале мой пакет просто сможет отображать собственные шаблоны администратора на отдельной части сайта, например /admin.

Ответ 1

Как отметил Джеймс Хэтфилд, Iron-Router теперь поддерживает несколько макетов. Для тех, кто сейчас нажимает этот поток, это лучший способ справиться с сценарием с несколькими макетами.

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

  @route 'dashboard',
    layoutTemplate: 'dashboardLayout'

Ответ 2

IronRouter поддерживает несколько макетов.

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>

Может работать очень хорошо, если вы сопоставляете его с проверками UserID Meteor и перехватами onBeforeRun. Я не полностью протестировал аспект безопасности, но похоже, что он будет работать.

Ответ 3

Пожалуйста, взгляните на мой проект в github. У меня есть решение для этого. Это может быть не самое лучшее, но оно работает до сих пор.

github.com/voteapp

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

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

Корневой шаблон использует некоторые другие шаблоны внутри. Я могу использовать 2 разных файла индекса. 1 для сайта и 1 для панели управления.

Корневой шаблон:

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

шаблон adminLogin:

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

шаблон сайта:

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

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

На самом деле это не html из моего проекта, но это что-то вроде этого. Таким образом, ссылки CSS появятся в конце тега body. А для панели администратора и самого сайта будут разные HTML-структуры и css файлы. Также вы можете также добавить файлы javasctipt.

Ответ 4

Привет и спасибо за ссылку на обсерваторию! Вы совершенно правы в том, что в конечном итоге было бы неплохо иметь управление и мониторинг отдельно, и на самом деле мы работаем в этом направлении в последнее время, и это также будет основным направлением - цель состоит в том, чтобы отслеживать, анализировать журналы и предоставить некоторые возможности управления в облаке. Он уже имеет некоторые базовые функции - проверьте здесь: http://vega.observatoryjs.com/demo

Кстати, как мы справлялись с вашей проблемой в оригинальной обсерватории - просто создайте отдельный маршрут в Pages или Iron Router и т.д. и разместите там шаблон обсерватории (или ваш админ-панель) - в нашем случае {{ > logs_bootstrap}}. Таким образом, он будет полностью отделен от основного приложения. Но облако еще лучше:)

Ответ 5

Разве это невозможно, просто используя маршрутизаторы Meteor и шаблоны:

Укажите маршруты:

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

Скажем, у вас есть раскладка в 3 столбцах. Создайте свой шаблон следующим образом:

<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>

Затем укажите свои помощники шаблонов:

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';
    }
  }
});