У современных веб-приложений нет причин не иметь постоянных ссылок (также известных как «красивые URL-адреса»). Их легче запомнить пользователям, важно для SEO, а при работе с Meteor чрезвычайно легко реализовать.
Чтобы продемонстрировать, как создать базовую систему постоянных ссылок, мы собираемся создать приложение блогов для блогов. По умолчанию каждое сообщение будет иметь URL-адрес, содержащий идентификатор сообщения, например: http://localhost:3000/post/pCZLhbwqtGXPdTDMM
.
Это самый простой подход, но полученный URL-адрес не очень хорош, поэтому мы узнаем, как заменить этот идентификатор пользовательским значением. Наши изменения позволят нам иметь такой URL: http://localhost:3000/post/hello-world
.
Попутно мы также изучим несколько других приемов, которые пригодятся при создании любого вида веб-приложений с Meteor . Если вы хотите поиграть с кодом, созданным в этой статье, я создал для вас репозиторий .
Давайте начнем!
Начиная
Внутри нового проекта Meteor установите Iron Router , выполнив команду:
meteor add iron:router
Для непосвященных, Iron Router является предпочтительным пакетом маршрутизации среди разработчиков Meteor, и он позволяет нам связывать шаблоны с URL-путями.
Например, мы можем создать «домашний» шаблон, подобный следующему:
<template name="home"> <form> <input type="text" name="title" placeholder="Title goes here..."> <textarea name="content" placeholder="Entry goes here..."></textarea> <input type="submit" value="Add Post"> </form> </template>
И затем маршрут для этого шаблона, как показано ниже:
Router.route('/', function(){ this.render('home'); });
После этого при каждом посещении корневого пути нашего приложения будет отображаться содержимое «домашнего» шаблона.
Написание сообщений
Чтобы хранить сообщения блога для нашего приложения, нам нужно создать коллекцию «сообщений»:
var Posts = new Meteor.Collection('posts');
Внутри isClient
выражения isClient
мы напишем операторы, которые добавят данные в эту коллекцию после isClient
формы внутри «домашнего» шаблона:
if(Meteor.isClient) { Template.home.events({ 'submit form': function(event){ event.preventDefault(); var title = event.target.title.value; var content = event.target.content.value; Posts.insert({ title: title, content: content }); } }); }
Нам также нужно, чтобы в каждом сообщении было поле «Постоянная ссылка», чтобы определить значение, которое будет отображаться в URL. Мне нравится устанавливать это поле в значение поля _id
по умолчанию.
Для этого сохраните значение, возвращаемое функцией insert()
внутри переменной, а затем вызовите функцию update()
как показано ниже:
var post = Posts.insert({ title: title, content: content }); Posts.update( { _id: post }, { $set: {permalink: post} } );
С этим кодом мы:
- Создание нового поста.
- Хранение идентификатора поста в переменной с именем
post
. - Обновление указанного поста.
- Установите в поле «постоянная ссылка» значение идентификатора записи.
Например, если вы создали сообщение с идентификатором «pCZLhbwqtGXPdTDMM», структура сообщения будет выглядеть следующим образом:
{ _id: 'pCZLhbwqtGXPdTDMM', title: 'Hello World', content: 'This is the content...', permalink: 'pCZLhbwqtGXPdTDMM' }
Вы также можете создать постоянную ссылку на основе заголовка поста — поэтому, если заголовок поста был «Hello World», постоянная ссылка была бы «hello-world» — но это немного выходит за рамки этого урока.
Страницы сообщений
Каждому сообщению в блоге нужна отдельная страница. Для начала, эти страницы будут опираться на идентификатор сообщения, а не на постоянную ссылку (даже если в настоящее время это те же значения, которые мы только что рассмотрели).
Сначала создайте шаблон «пост» для этих страниц поста:
<template name="post"> <h1>{{title}}</h1> <div class="entry"> {{content}} </div> </template>
Затем создайте маршрут:
Router.route('/post/:_id', function(){ var postId = this.params._id; this.render('post', { data: function(){ return Posts.findOne(postId); } }); });
В этом коде мы:
- Извлечение поля
_id
из URL. - Сохранение этого значения в переменной «postId».
- Получение документа на основе этого идентификатора.
В результате, если сообщение имеет идентификатор «pCZLhbwqtGXPdTDMM», это сообщение станет доступным через URL-адрес http://localhost:3000/post/pCZLhbwqtGXPdTDMM
.
Вам не нужна часть «/ post» в URL, и вы можете изменить код маршрута следующим образом, чтобы удалить эту часть URL:
Router.route('/:_id', function(){ var postId = this.params._id; this.render('post', { data: function(){ return Posts.findOne(postId); } }); });
После этого изменения URL-адрес той же страницы поста станет http://localhost:3000/pCZLhbwqtGXPdTDMM
.
Редактирование поля «Постоянная ссылка»
Мы близки к добавлению поддержки постоянных ссылок в приложение, но сначала давайте напишем код для редактирования поля «постоянная ссылка». Для этого нам нужно обновить шаблон «post», добавив поле «permalink». Мы также добавим атрибут contentEditable
в окружающий элемент div
. Используя этот атрибут, мы сможем напрямую отредактировать поле постоянной ссылки на странице, хотя нам нужно будет построить логику, чтобы это работало. Полученный код шаблона показан ниже:
<template name="post"> <h1>{{title}}</h1> <div class="permalink" contenteditable="true">{{permalink}}</div> <div class="entry"> {{content}} </div> </template>
Чтобы создать упомянутую ранее бизнес-логику, создайте событие, которое позволит пользователям редактировать значение элемента «постоянная ссылка» и нажмите клавишу «Return», чтобы сохранить это значение в базе данных. Код для создания такого события показан ниже:
Template.post.events({ 'keypress .permalink': function(event, template){ var permalink = template.find('.permalink').innerHTML; if(event.which === 13){ event.preventDefault(); Posts.update({_id: this._id}, {$set: {permalink: permalink}}); event.target.blur(); } } });
Вот как это работает:
- Событие
keypress
запускается, когда пользователь нажимает клавишу, фокусируясь на элементе, имеющем классpermalink
. - Содержимое поля «постоянная ссылка» извлекается с помощью функции
template.find
и сохраняется в переменной «постоянная ссылка». - Если нажать клавишу «Return», значение в переменной «permalink» сохраняется в базе данных, перезаписывая старое значение.
Как только вы завершите этот последний шаг, пользовательский интерфейс будет выглядеть так:
Добавление поддержки постоянной ссылки
До этого момента мы установили почти весь необходимый код. Однако, чтобы постоянные ссылки работали, как запланировано, вы должны изменить код, который обрабатывает маршрут, следующим образом:
Router.route('/post/:permalink', function(){ var permalinkValue = this.params.permalink; this.render('post', { data: function(){ return Posts.findOne({permalink: permalinkValue}); } }); });
Здесь происходит несколько вещей:
- Путь маршрута содержит параметр «постоянная ссылка» вместо параметра «_id».
- Вместо использования переменной «postId» у нас есть переменная «permalinkValue».
- Функция
findOne
была изменена для выполнения поиска на основе значения поляpermalink
, а не поля_id
.
В результате URL http://localhost:3000/post/pCZLhbwqtGXPdTDMM
больше не будет работать, но будет работать http://localhost:3000/post/hello-world
.
Аккуратно, не правда ли?
Изменение постоянной ссылки
В настоящий момент, если пользователь изменит постоянную ссылку на страницу, эта страница будет повреждена. Мы можем исправить это так, чтобы сразу после изменения постоянной ссылки пользователь перенаправлялся на новый маршрут.
Для этого добавьте параметр «имя» в маршрут нашего сообщения:
Router.route('/post/:permalink', function(){ var permalinkValue = this.params.permalink; this.render('post', { data: function(){ return Posts.findOne({permalink: permalinkValue}); } }); }, { name: 'post' });
Затем добавьте функцию Router.go
к событию keypress
:
Template.post.events({ 'keypress .permalink': function(event, template){ var permalink = template.find('.permalink').innerHTML; if(event.which == 13){ event.preventDefault(); Posts.update({_id: this._id}, {$set: {permalink: permalink}}); event.target.blur(); Router.go('post', {permalink: permalink}); } } });
Здесь мы используем эту функцию Router.go
для перенаправления на «почтовый» маршрут, используя отредактированное значение поля постоянной ссылки.
Выводы
Настройка основ системы постоянных ссылок достаточно проста. Сложная часть — это все дополнительные детали, которые необходимо учитывать. Вот несколько вопросов для размышления:
- Что произойдет, если пользователь попытается определить постоянную ссылку, которая уже была определена для отдельной страницы?
- Какие ограничения следует применять при определении постоянной ссылки? (Длина, разрешенные типы символов и т. Д.)
- Как можно автоматически создать постоянную ссылку на основе заголовка сообщения в блоге вместо использования идентификатора сообщения в постоянной ссылке по умолчанию?
Эти проблемы — хорошее упражнение для проверки ваших знаний. Так что вы можете заняться ими в свое время. Если вы хотите поиграть с кодом, созданным в этой статье, я создал для вас репозиторий .