Skip to content Skip to sidebar Skip to footer

A Way To Precompile Slim Templates On Server Side And Pass Html To Vuejs In Rails App?

I'm trying to integrate Vue js in existing rails app with lots of slim templates. It would be nice if I could use vue directives in slim templates (yes, it's possible), get an HT

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'endend

classTemplatesController < ApplicationControllerdefshowif lookup_context.exists?(params[:path])
      render template: params[:path]
    else
      head :not_foundendendend

require 'rails_helper'

RSpec.describe "Templates", type: :request do
  describe "GET /template/*path"do
    it "fetches template if it exists"doget'/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"doget'/templates/foo/non_existant.html.erb'
      expect(response).to have_http_status(:not_found)
    endendend

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:

classApplicationController < ActionController::Base
  before_action :add_html_to_template_lookup!, if: -> { request.format.template? }
  layout :is_template_request?

  private

  defis_template_request?
    request.format.template? ? false : "application"end# this will make rails fall back to rendering the "normal" html viewsdefadd_html_to_template_lookup!
    request.formats << Mime::Type.lookup("text/html")
  endend

Post a Comment for "A Way To Precompile Slim Templates On Server Side And Pass Html To Vuejs In Rails App?"