A Way To Precompile Slim Templates On Server Side And Pass HTML To VueJS In Rails App?
Solution 1:
The solution I've found is quite simple. All you need to do is wrap your slim markup inside of vue component tag in your .slim views, and add inline-template attribute to it.
Example:
# header.html.slim
<v-header inline-template>
header
nav
- categories.each do |category|
= link_to category.name, category, '@click.prevent': 'doSomething'
</v-header>
or
v-header inline-template=""
header
nav
- categories.each do |category|
= link_to category.name, category, '@click': 'doSomething'
Ruby code will be executed first, template engine will convert everything to html with vue directives, then Vue will recognize its directives and take control of the markup. After I implemented this, I got rid of jquery and asset pipeline. But the views are the same. I did not migrate any of html files to vue components. With this feature, you can partially apply Vue js to your existing rails project and start writing modern javascript code.
Solution 2:
There is no silver bullet to combine server-side and client-side templating. Even if you can render vue templates on the server the key context is missing (the interactive state of the page in the client).
There are some rather simple but flawed techniques that you could use to combine server-side and client rendering:
Create a controller that serves up your views
Rails.application.routes.draw do
scope 'templates' do
get '*path', to: 'templates#show'
end
end
class TemplatesController < ApplicationController
def show
if lookup_context.exists?(params[:path])
render template: params[:path]
else
head :not_found
end
end
end
require 'rails_helper'
RSpec.describe "Templates", type: :request do
describe "GET /template/*path" do
it "fetches template if it exists" do
get '/templates/foo/bar.html.erb'
expect(response).to have_http_status(200)
expect(response.body).to match "TEST"
end
it "returns 404 if it does not exist" do
get '/templates/foo/non_existant.html.erb'
expect(response).to have_http_status(:not_found)
end
end
end
However the devil is in details - this would only really work if your views are completely static and do not need any input data.
Render views without a layout
If you instead want to render normally from your controllers but not include the entire layout you can register a custom format:
# config/initializers/mime_types.rb
Mime::Type.register "text/x-html-template", :template
Sometimes you may need to stop spring in order for configuration changes to be picked up.
You can then disable the layout for this format:
class ApplicationController < ActionController::Base
before_action :add_html_to_template_lookup!, if: -> { request.format.template? }
layout :is_template_request?
private
def is_template_request?
request.format.template? ? false : "application"
end
# this will make rails fall back to rendering the "normal" html views
def add_html_to_template_lookup!
request.formats << Mime::Type.lookup("text/html")
end
end
Post a Comment for "A Way To Precompile Slim Templates On Server Side And Pass HTML To VueJS In Rails App?"