This gem introduces a quick and easy way to write frontends for your Rails app in VueJS.
With RailsPages, each webpage has a back-end and front-end that exist side-by-side.
This gem introduces a new top-level directory called pages
.
Each folder inside pages
can contain a single page.
.
└── app
├── models
├── views
├── controllers
└── pages
└── my_page
├── page.rb
└── page.vue
Each page is expected to have a page.rb
and a page.vue
, representing the back-end portion and front-end portion respectively.
The page's definition exists inside of page_name/page.rb
.
# app/pages/my_page/page.rb
Page.define '/actual/url/path/here' do
authorize { true } # <- an "authorize" block must always be provided but the authorization itself can be done on the pages/page controller
data do
{ value: 'hello!' } # <- can use in page.vue
end
end
As you can see, the above definition includes the actual URL path. This means the URL of each page of apparent when looking at the source code, and so developers don't need to dig into routes.rb quite as often.
The frontend portion is just a regular VueJS component.
<!-- pages/my_page/page.vue -->
<template>
<h1>{{ value }}</h1>
<p>{{ dogicaCoin }}</p>
</template>
<script>
import { ref } from 'vue'
export default {
data() {
const dogicaCoin = ref(100) // you can declare new reactive data here
return {
value: '', // <- value comes directly from page.rb!
dogicaCoin
}
}
}
</script>
When the page is loaded, the data
block from page.rb
is sent to page.vue
automatically.
Rails pages supports by default GET
and POST
requests. The following is an example of how you could do it:
# app/pages/my_page/page.rb
post 'convert' do # you can use post/get HTTP requests like this
if params[:value] > 9000
render json: {
message: 'Successfully converted DogicaCoin!'
}
else
render json: {
error: 'Insufficient DogicaCoin :sad'
}
end
end
// app/pages/my_page/page.vue
import { post } from 'rails-pages'
async convert(value) {
const result = await post('convert', { value: value });
if (result.error) {
this.$toast.error(result.error);
} else {
this.$toast.success(result.message);
}
}
TODO: cover using RailsPages::Page
as a proper Model, metadata, etc.
Add this line to your application's Gemfile:
gem 'rails_pages'
And then execute:
$ bundle install
Pages are executed in the context of a regular Rails controller. When you install RailsPages, you will need to make that controller yourself. This allows you the flexibility to handle things like user authentication freely.
You can call your pages controller anything you like. Here's the simplest possible implementation:
class PagesController < ApplicationController
include RailsPages::ControllerActions
end
Each page has its own route, and so each page must be "mounted" individually.
In the simplest case, you can mount every page, all in one go.
# config/routes.rb
# This require is necessary to add the `mount_pages` and `mount_page` helpers.
require 'rails_pages/routes'
Rails.application.routes.draw do
mount_pages RailsPages::Page.all, to: 'pages'
end
TODO: make this real and then explain it
Have any ideas or fixes? Feel free to fork and make a PR! We'll do our best to review your code and get it merged.
The gem is available as open source under the terms of the MIT License.