Создание блога на Dart. Часть 2.
Создание блога на Dart. Часть 1.
Создание блога на Dart. Часть 2.
Создание блога на Dart. Часть 3.
Роутинг
Роутинг я реализовал просто — обработкой запросов занимаются контроллеры, каждый из которых сам решает, может он обработать запрос или нет. Запрос обрабатывается первым подходящим контроллером.
Класс базового контроллера:
abstract class ControllerBase { Future processRequest(HttpRequest request); Future<bool> canProcessRequest(HttpRequest request); }
Базовый класс для контроллеров, возвращающих HTML:
abstract class HttpController extends ControllerBase { Future processRequest(HttpRequest request) async { request.response.headers.contentType = ContentType.HTML; } }
Класс контроллера, отдающего содержимое поста по пермалинку:
class PostController extends HttpController { PostRepository postRepository = injector.get(PostRepository); PostController() {} Future processRequest(HttpRequest request) async { await super.processRequest(request); var requestPermalink = StringUtils.Trim(request.requestedUri.path, '/'); postRepository.getAllPosts().then((List<Post> posts) { var post = posts.where((p) => p.permalink == requestPermalink).single; request.response ..write(post.body) ..close(); }); } Future<bool> canProcessRequest(HttpRequest request) { var requestPermalink = StringUtils.Trim(request.requestedUri.path, '/'); return postRepository.getAllPosts().then((List<Post> posts) { return posts.any((p) => p.permalink == requestPermalink); }); } }
Урл для этого контроллера выглядит так: /permalink
Из репозитория постов получаются все посты, из них выбирается единственный с соответствующим пермалинком и в ответ пишется содержимое поста. Верстку и шаблонизацию пока не делал, хотя пара шаблонизаторов для Dart есть.
Класс контроллера, отдающего список постов:
class ListController extends HttpController { PostRepository postRepository = injector.get(PostRepository); static const int postsPerPage = 2; Future processRequest(HttpRequest request) async { await super.processRequest(request); int pageNum = int.parse(request.requestedUri.queryParameters["p"]); List<Post> posts = await postRepository.getAllPosts(); List<Post> shownPosts = posts.skip(postsPerPage * (pageNum - 1)).take(postsPerPage).toList(); shownPosts.forEach((Post post) { request.response ..write("<h1>${post.title}</h1><br>${post.body}<br><br><br>"); }); request.response.close(); } Future<bool> canProcessRequest(HttpRequest request) async { var requestlink = StringUtils.Trim(request.requestedUri.path, '/'); if (requestlink != 'list') return false; if (!request.requestedUri.queryParameters.containsKey("p")) return false; return true; } }
Полезные мелочи
В базовой библиотеке Dart пока не хватает всех привычных полезных функций, так что trim() для строки пришлось делать самому:
class StringUtils { static String Trim(String string, String part) { if (part.length != 1) throw new ArgumentError('part.length should be equal to 1'); String result = string; if (result.startsWith(part)) result = result.substring(1); if (result.endsWith(part)) result = result.substring(0, result.length - 1); return result; } }