Giter VIP home page Giter VIP logo

panoramic's Introduction

Panoramic Build Status

An ActionView::Resolver implementation to store rails views (layouts, templates and partials) on database. Simply put: what you can do with views on filesystem, can be done on database.

NOTE: at the moment, only ActiveRecord is supported, I've planned to add more ORMs (see Todo). If you can't wait, adding other ORMs should be very trivial.

Installation

Add the following line to Gemfile:

gem "panoramic"

Usage

Mandatory fields

Your model should have the following fields:

  • body (text): the source of template
  • path (string): where to find template (ex: layouts/application, you_controller/action, etc...)
  • locale (string): it depends from available locales in your app
  • handler (string): as locale field, it depends from avaiable handlers (erb, haml, etc...)
  • partial (boolean): determines if it's a partial or not (false by default)
  • format (string): A valid mimetype from Mime::SET.symbols

they're what the rails' Resolver API needs to lookup templates.

Model

A simple macro in model will activate your new Resolver. You can use a dedicated model to manage all the views in your app, or just for specific needs (ex: you want a custom template for some static pages, the other views will be fetched from filesystem).

class TemplateStorage < ActiveRecord::Base
  store_templates
end

Controller

To add Panoramic::Resolver in controller, depending on your needs, you may choose:

  • prepend_view_path: search for templates first in your resolver, then on filesystem
  • append_view_path: search for templates first on filesystem, then in your resolver

NOTE: the above methods are both class and instance methods.

class SomeController < ApplicationController
  prepend_view_path TemplateStorage.resolver

  def index
    # as you may already know, rails will serve 'some/index' template by default, but it doesn't care where it is stored.
  end

  def show
    # explicit render
    render :template => 'custom_template'
  end

  def custom_template
    # use another model to fetch templates
    prepend_view_path AnotherModel.resolver
  end
end

And let's say you want to use database template resolving in all your controllers, but want to use panoramic only for certain paths (prefixed with X) you can use

class ApplicationController < ActionController::Base
  prepend_view_path TemplateStorage.resolver(:only => 'use_this_prefix_only')
end

This helps reducing the number of database requests, if Rails for example tries to look for layouts per controller.

ActionMailer

class MyEmail < ActionMailer::Base
  prepend_view_path TemplateStorage.resolver

Using prepend_view_path/append_view_path you are stuck to the current context (e.g. the method calling "mail"). If you want to dynamically change the path depending on a certain variable, call the prepend_view_path/append_view_path inside the method's context with an additional path variable. This could be useful, if you want to use only one method for sending different templates depending on the template.path .

class MyEmail < ActionMailer::Base

  def method_that_sets_resolver_path
    prepend_view_path TemplateStorage.resolver(:path => model.path)
  end

Documentation

Need more help? Check out spec/dummy/, you'll find a dummy rails app I used to make tests ;-)

Testing

Enter Panoramic gem path, run bundle install to install development and test dependencies, then rake spec.

Todo

Long term

  • add generators

Contributing

Fork, make your changes, then send a pull request.

Credits

The main idea was heavily inspired from José Valim's awesome book Crafting Rails Applications. It helped me to better understand some Rails internals.

panoramic's People

Contributors

abstracts33d avatar alessiorocco avatar alto avatar andreapavoni avatar dependabot[bot] avatar fastjames avatar gealgaro avatar ndbroadbent avatar nhodges avatar pragmaticsc avatar rubybrewsday avatar rud avatar viehlieb avatar vortexgrenade avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

panoramic's Issues

Is there a way to have multiple formats without duplicating record

I want something like this for example:

TemplateStorage.create(body: '###mailer with text and html format', path: 'user_mailer/testing', handler: 'liqmd', formats: ['html', 'text'])

here handler: 'liqmd' is the liquid_markdown gem which I am working on. That's the reason I don't have to duplicate records for format: 'html' and format: 'text' with exactly same body. So it would be great if I can put both html and text together in format column.

It is working well if I duplicate record with format: 'html' and format: 'text'

TemplateStorage.create(body: '###mailer with text and html format', path: 'user_mailer/testing', handler: 'liqmd', format: 'html')
TemplateStorage.create(body: '###mailer with text and html format', path: 'user_mailer/testing', handler: 'liqmd', format: 'text')

Thanks

Minor Documentation glitch

Within section Installation, it must read:

gem "panoramic", "~> 0.0.2"

Within section Usage/Mandatory fiels, the following line ist missing:

format (string): A valid mimetype from Mime::SET.symbols

Using "themes" (feature request or question how to do that)

Firstly, congratulations for this initiative.

Is there a way for scoping template model like the following?

class ApplicationController < ActionController::Base
  before_filter :database_template

  def database_template
    prepend_view_path DatabaseTemplate.where(theme: current_theme).resolver
  end

  def current_theme
    # find theme picked by user
  end
end

Thanks!

Rails dependency

I have the following Rails dependency in my project Gemfile:

gem "rails", "3.2.1"

If I try to add Panoramic, I get the following error when running bundle:

Bundler could not find compatible versions for gem "rails":
    In Gemfile:
        panoramic depends on
            rails (~> 3.0.7)

        rails (3.2.1)

how to ignore locale?

Hi, first at all thanks for this gem.
Im storing a diferent template for each view, but i dont want to specify the locale.
I have made 2 tests:

  1. removed the field from the form -> template is not saved.
  2. leave the field blank -> "error (not in the list)"

any ideas?

rails 6.1 ArgumentError missing keyword: locals

In rails 6.1 the gem does not work narrowed it down to lib/panoramic/resolver.rb 46

actionview (6.1.0) lib/action_view/template.rb initialize
initalize(source, identifier, handler, locals:, format: nil, variant: nil, virtual_path: nil)
the call to add is made like this

ActionView::Template.new(source, identifier, handler, details)

which does not include locals named argument

was not throwing an error in 6.0 because of default value provided
initalize(source, identifier, handler, format: nil, variant: nil, locals: nil, virtual_path: nil, updated_at: nil)

can be fixed for 6.1 like this

      ActionView::Template.new(source, identifier, handler,
                               :locals => [],
                               :format => Mime[record.format].to_sym,
                               :virtual_path => virtual_path(record.path, record.partial))

not sure of what is needed to make it compatible with all versions

here is a pr regarding the fix for 6.1
PR 46

Gem release

Latest gem release was in 2012. Any chance you could release a newer version?

How to query templates table within mailer ?

Hi

If I have multiple templates stored in my database - how can I perform a query in my mailer so that my mailer retrieves the template I want to use and uses that to generate the mail message ?

The documentation contains the following snippet ...

class MyEmail < ActionMailer::Base
  prepend_view_path TemplateStorage.resolver

but that doesn't give me the control that I need to retrieve the template my mailer needs to use based on supplied criteria

how can I modify the call above ( prepend_view_path TemplateStorage.resolver ) so that arguments are passed to the 'resolver' which can be used to query my templates table and only retrieve the needed template ?

Thanks
Dave

Scoping templates by theme in a CMS

Hi! I am working on a CMS that lets users create/manage templates. These templates should be scoped by theme though. What is the best way to achieve this with panoramic? I see that there is a related issue but it's very old and I think it no longer applies to current versions of the gem and Rails. Thanks in advance for any help!

Some Help?

Could you please show some example data that goes into these fields:

body (text): the source of template (I understand this one)
path (string): where to find template (would 'views/reports' work?)
locale (string): it depends from available locales in your app
handler (string): as locale field, it depends from avaiable handlers (erb, haml, etc...)
partial (boolean): determines if it's a partial or not (false by default)
format (string): A valid mimetype from Mime::SET.symbols

Do they all need to have data? I'm getting 'is not included in the list' when empty.

I'm trying to store a xlsx template in the database. Does this look right?
Path = vehicles/evlist
Locale = en
Handler = axslx
Format = xlsx

NEVER MIND - I got it to work!

Thanks!!!

Adding criteria to find_model_templates

Is there a workflow to add criteria to the finder for templates, for example having different templates per user?

For that, I suppose we would have to somehow pass the @current_user to the finder in the controller, and for that to hook into panoramic.

Is this repo still maintained?

Thank you for your work on this gem!

I would kindly ask if it is still maintained since the PR-queue is long..

Best wishes!

Template errors raise ActionView::MissingTemplate

If an exception is raised from a template stored in the database, ActionView::MissingTemplate is thrown which makes it look like the template doesn't exist. The original exception is masked. This makes it impossible to diagnose what's wrong with the template. It would be nice if the gem offered better error handling that actually surfaced the exception from the template.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.