Створення движка для блогу за допомогою Phoenix та Elixir

Від перекладача: «Elixir і Phoenix — чудовий приклад того, куди рухається сучасна веб-розробка. Вже зараз ці інструменти надають якісний доступ до технологій реального часу для веб-додатків. Сайти з підвищеною інтерактивністю, розраховані на багато користувачів браузерні ігри, мікросервіси - ті напрямки, в яких дані технології співслужать хорошу службу. Далі представлений переклад серії з 11 статей, які докладно описують аспекти розробки на фреймворку Фенікс здавалося б такої тривіальної речі, як блоговий движок. Але не поспішайте кукситися, буде дійсно цікаво, особливо якщо статті спонукають вас звернути увагу на Еліксір або стати його послідовниками.
На даний момент наш додаток заснований на:
На чому ми зупинилися
Додаємо канали
А потім створимо сам канал, з яким працюватимемо. Для цього скористаємося генератором Phoenix:
- Коментар створено
- Коментарій видалено
- Коментар схвалений
Для всіх:
- Коментар схвалений
- Коментарій видалено
Спочатку нам потрібно налаштувати деякі базові речі. Додамо jQuery до програми, щоб легше взаємодіяти з DOM.
Додавання jQuery за допомогою Brunch
Почнемо з встановлення jQuery через NPM.
А потім перезавантажимо сервер Phoenix і перевіримо, що jQuery успішно встановився. Відкрийте файлweb/static/js/app.js та додайте вниз наступний код:
Якщо ви побачили повідомлення «jquery works!» у Developer Console браузера, можна видаляти ці рядки і переходити до наступного кроку.
Реалізація каналів на Javascript
Потімвідкриємо файл web/static/js/socket.js і внесемо кілька невеликих правок:
Потім приступимо до додавання обробників подій у каналі для кожного з цих дій.
Доопрацювання коду для підтримки каналів
Якщо спробувати протестувати у браузері, програма впаде. Ви отримаєте повідомлення про помилку на кшталт цього:
Зараз у нас немає функції для обробки повідомлень усередині каналу. Відкрийте файл web/channels/comment_channel.ex і давайте зробимо так, щоб функція handle_in транслювала повідомлення передплатникам замість того, щоб мовчки спостерігати. Нам також потрібно змінити стандартну функцію join угорі:
Тепер ми можемо додати подібний код для двох інших повідомлень, які ми маємо на увазі слухати.
Нам також потрібно внести декілька правок до шаблонів. Необхідно знати, з яким постом ми працюємо і ким є поточний користувач. Таким чином, додамо нагору файлу web/templates/post/show.html.eex наступний код:
Потім відкрийте файл web/templates/comment/comment.html.eex і змініть відкриваючий div:
Зараз необхідно реалізувати кожну з можливостей транслювання належним чином, тож повернемося на «полі джаваскрипту» і продовжимо!
Реалізація ідентифікатора користувача через Phoenix.Token
Почнемо з проставлення токена користувача в шаблон програми. Це досить зручно, адже можливо ми захочемо відображати його скрізь. У файлі web/templates/layout/app.html.eex додайте наступне до інших мета-тегів:
Тут ми говоримо, що хочемо підписаний токен, який вказує на ідентифікатор користувача (звісно, якщо користувач увійшов до системи). Це дасть нам чудовий спосіб для перевірки користувача user_id через Javascript без необхідності довіряти прихованим полям введення абокористуватися іншими дивними способами.
Далі у файлі web/static/js/socket.js , внесіть кілька змін до коду з'єднання сокету:
Тепер передамо валідний токен назад у код Phoenix. На цей раз нам потрібен файл web/channels/user_socket.ex , в якому змінимо функцію connect для перевірки токена користувача:
Отже, ми викликаємо функцію verify з модуля Phoenix.Token і передаємо до неї сокет, значення для перевірки, сам токен і значення max_age (максимальний час життя токена, наприклад, два тижні).
Якщо верифікація пройшла успішно, то відправимо назад кортеж , яким у разі є user_id. Потім підтримаємо з'єднання зі значенням user_id, збереженим у сокеті (подібно до збереження значення в сесії або conn).
Повертаємось до Socket.js
Нам знадобиться тонна Javascript-коду для підтримки всього задуманого. Розглянемо завдання докладніше:
А я попереджав вас, що тут буде повно джаваскрипта :) Давайте не втрачатимемо часу і відразу приступимо до написання кожної з цих функцій. Коментарі в даному шматку коду описують кожну з вимог відповідно.
Допоміжні функції для каналів
Почнемо згори. Ми будемо часто звертатися до модулів Comment/Post/User/Repo, так що для чистоти коду правильно буде додати для них аліаси. Ми також повинні імпортувати функцію build_assoc з Ecto , але тільки версію арності 2.
Авторизація здійснюється всередині функції, а потім виконуються дії, передані за допомогою блоку fn -> . end. Це добрий зразок, коли дублюється багато логіки.
З функції authorize_and_perform достатньо. Перейдемо до функції delete:
Зрештою, поглянемо на допоміжні функції менше.
Все, що нам потрібно - замінити початковий код зповідомленнями CREATED/APPROVED/DELETED на допоміжні функції. Відкрийте файл web/channels/comment_channel.ex:
Принципи схожі у всіх трьох викликах, так що розберемо тільки create:

Висновок
Дизайн, як і раніше, поганий, так що потрібно зайнятися і ним. Для цього додамо Zurb Foundation 6 та створимо чистий зовнішній вигляд нашої блогової платформи!
Інші статті серії
Скромний висновок від перекладача
А у нас тут можна отримати грант на тестовий період Яндекс.Хмари. Варто лише у полі «секретний пароль» запровадити «Хабр»