Arief R Ramadhan
Arief R Ramadhan

Reputation: 234

Generating Javascript Code with Rails

I'm currently developing a web app which can generate JS code that can attached to another page. Just like email subscription form which generated from the form builder below:

<script type="text/javascript" src="https://app.getresponse.com/view_webform_v2.js?u=BB1K&webforms_id=1523701"></script>

Instead of generating subscription form, I want the JS code to render image or text and I want to put the image or text inputted to the file storage such as AWS instead within my app.

I'm running on Rails 4.2.5.

The above JS code is generating a form, the form must be saved somewhere in the file storage (CMIIW). I want to make an app which can generate that kind of JS code.

P.S. I'm new to Rails, anyone can please explain the process or is there any gem that can help achieve this task. Thank you.

Upvotes: 2

Views: 934

Answers (2)

Richard Peck
Richard Peck

Reputation: 76784

So what you want is a widget.


Public

The underpin of this is that you need a public JS file to "pull" data from your app & show the appropriate HTML on someone else's site.

This file will be included on the other person's site; it will populate HTML elements on the site with data from your server (through an API). It may use an iframe, but more often than not will just decorate an HTML element with assets from your own server.

All of the widgets / badges / buttons you can put on your site are just embedded JS from someone else's. These JS files need to work with public data from your app (IE you cannot use ANY server-side tech with it)...

# public/your_widget.js
// put new element on page
// populate with form data

--

JS

The only way you can make a JS file public is by placing it in your public folder, or at least a publicly-accessible part of your app (subdomain).

You cannot use the asset pipeline for it.

Of course, there are version control mechanisms you can use etc, but the fact is that you need a public "link" other sites can include:

<script src="http://api.yoursite.com/public.js"></script>

--

HTML

In order to populate a widget on your site, you can look at the various JS adaptations which exist. I've not had massive experience of this; bootstrap's JS implementation would be a good place to start, and Google's analytics JS.

In short, your JS needs to generate HTML & output it on your site.

The standard pattern for this is to include the script on your site, place an HTML "element" (with appropriate id) on your page, to which the JS will populate with HTML (pre-cooked with data from your server):

// site
<script "http://api.yoursite.com/public.js"></script>
<body>
   <div id="your_widget" data-name="tester" data-attribute="value"></div>
</body>

// JS

--

Data

To populate the data on your site, you'll need to use an API - publicly accessible:

#config/routes.rb
scope constraints: { subdomain: "api" } do
   resources :images, module: :api #-> api.url.com/images/x
end

This would have to be backed up with authentication similar to your app (my API authentication integration is a little hazy):

#app/models/user.rb
class User < ActiveRecord::Base
   has_secure_token #-> native to Rails 5; gem for Rails 4
end

#app/controllers/api/images_controller.rb
class Api::ImagesController
   before_filter :authenticate

   def show
       user  = User.find_by token: request.headers["Auth_Key"]
       image = user.images.find params[:id]
       render json: image.to_json if image
   end

   private

   def authenticate
      if request.headers.include? "Auth_Key"
         render :unprocessable_entity unless User.exists? token: request.headers["Auth_Key"]
      end
   end
end

Ref

The above code is just a general example.

It will allow you to send...

var image_url = $.ajax({
   url:     "http://api.url.com/images/x",
   headers: "Auth-Key": "x"
});

CORS

Finally, the last consideration is CORS - Cross Origin Resource Sharing:

Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources (e.g. fonts & javascript) on a web page to be requested from another domain outside the domain from which the resource originated

In other words, you cannot just let anyone pull your JS files from your server. HTTP won't allow it unless you give them permission with a correct CORS policy.

What you need to do is make your public.js accessible to anyone, along with your API. It might - therefore - be recommended to put both into a subdomain. I can give you more info on this if required.


is there any gem that can help achieve this task

Not that I know of.

This is somewhat advanced functionality. You have to know the underlying authentication pattern for an HTTP web service, and match that with a JS implementation for use on third parties.

In its simplest form, you're making a tiny app ("widget") which pulls API data. You just have to know which parts of your app to allow access to, in order to make the functionality work.

Upvotes: 1

dpaluy
dpaluy

Reputation: 3715

In order to generate JS file and store in in S3 you should do the following:

  1. Create a file in TMP folder
  2. Upload it to S3

Creating a file:

The best practise is to create a Service, for example:

# app/services/js_generator.rb
class JsGenerator
  def initialize(some, params, here)
   @params = params
   # ...
  end

  def generate_code
    js = <<-END.squish
      var yourJavaScriptCode = "here";
      var embededExample = #{params};
      # ... etc
    END
  end

  def generate_and_save(tmp_file_name)
    code = generate_code
    tmp_file = "#{Rails.root}/tmp/#{tmp_file_name}.js"
    File.open(tmp_file, 'w') do |f|
      f.write code
    end
    tmp_file
  end
end

Uploading file to S3:

You have many options. I suggest using Fog to upload the file.

Upvotes: 0

Related Questions