Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## 3.1.1 (April 11, 2018)
- Add CNAME parameter

## 3.1.0 (August 4, 2017)
- Update Filestack::Ruby dependency to latest version to address namespacing issue

Expand Down Expand Up @@ -136,4 +139,4 @@ This is the last version that uses the

The changelog began with version 1.0.0 so any changes prior to that
can be seen by checking the tagged releases and reading git commit
messages.
messages.
122 changes: 63 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
[![Travis CI][travis_ci_badge]][travis_ci]
[![Coveralls][coveralls_badge]][coveralls]
[![Code Climate][code_climate_badge]][code_climate]
<p align="center"><img src="https://filestack.com/themes/filestack/assets/images/press-articles/color.svg" align="center" width="100"/></p>
<h1 align="center">Filestack::Rails SDK</h1>
<p align="center">
<a href="https://travis-ci.org/filestack/filestack-rails">
<img src="https://img.shields.io/travis/filestack/filestack-rails/master.svg?longCache=true&style=flat-square">
</a>
<a href="https://coveralls.io/github/filestack/filestack-rails?branch=master">
<img src="https://img.shields.io/coveralls/github/filestack/filestack-rails/master.svg?longCache=true&style=flat-square">
</a>
</p>
<p align="center">
Rails SDK for Filestack API and content management system.
</p>

# Filestack::Rails
<a href="https://www.filestack.com"><img src="https://filestack.com/themes/filestack/assets/images/press-articles/color.svg" align="left" hspace="10" vspace="6"></a>
This is the official Rails plugin for Filestack - API and content management system that makes it easy to add powerful file uploading and transformation capabilities to any web or mobile application.
**Important: This is the readme for 3.1.0+.**

## Resources
Note that the [Filestack::Ruby](https://github.com/filestack/filestack-ruby/) dependency has been updated to no longer interfere with namespace. However, if you were using that dependency in your Rails application, you will need to change any `Client` and `Filelink` class declarations to `FilestackClient` and `FilestackFilelink`, as per documented [here](https://github.com/filestack/filestack-ruby/blob/master/README.md).

* [Filestack](https://www.filestack.com)
* [Documentation](https://www.filestack.com/docs)
* [API Reference](https://filestack.github.io/)
## Overview

## IMPORTANT
Users of 3.0.0 wishing to upgrade to 3.1.0+ should note that the Filestack::Ruby dependency has been updated to no longer interfere with namespace. However, if you were using that dependency in your Rails app, you will need to change any Client and Filelink class declarations to FilestackClient and FilestackFilelink, as per documented [here](https://github.com/filestack/filestack-ruby/blob/master/README.md)
* A multi-part uploader powered on the backend by the [Filestack CIN](https://www.filestack.com/products/content-ingestion-network).
* An interface to the [Filestack Processing Engine](https://www.filestack.com/docs/image-transformations) for transforming assets via URLs.
* The Filestack Picker - an upload widget for the web that integrates over a dozen cloud providers and provides pre-upload image editing.

## Installing
## Installation

Add this line to your application's Gemfile:
Add this line to your application's `Gemfile`:

```ruby
gem 'filestack-rails'
Expand All @@ -35,54 +42,63 @@ Add the Filestack File Picker and initialization script to your layout:

```erb
<%= filestack_js_include_tag %>
<%= filestack_js_init_tag %>
<%= filestack_js_init_tag %>
```

Please note: the scripts need to be added before your application's custom scripts, e.g. before any scripts in your assets folder, if you need access the Filestack client in your own Javascript.
**Please note:** The scripts need to be added before your application's custom scripts, e.g. before any scripts in your assets folder, if you need access the Filestack client in your own Javascript.

Set your API key and client name in `config/application.rb`:

```ruby
config.filestack_rails.api_key = "Your Filestack API Key"
config.filestack_rails.client_name = "custom_client_name"
config.filestack_rails.api_key = 'Your Filestack API Key'
config.filestack_rails.client_name = 'custom_client_name'
```
The client name defaults to `"filestack_client"` and is injected into your client-side Javascript. This is because v3 of the File Picker lives in the Javascript of your web application.

### CNAME

If you have set up a custom CNAME, you can add it to your configuration file. The Picker will modify all assets to formatted with your domain origin instead of Filestack's.

Set your CNAME in `config/application.rb`:

```ruby
config.filestack_rails.cname = 'custom_cname'
```
The client name defaults to "filestack_client" and is injected into your client-side Javascript. This is because v3 of the File Picker lives in the Javascript of your web application. For more information, please see our [File Picker documenation](https://www.filestack.com/docs/javascript-api/pick-v3).

### Security

If your account has security enabled, then you must initialize the File Picker with a signature and policy. This is easily enabled through the configuration options by setting your application secret and security options:
If your account has security enabled, then you must initialize the File Picker with a signature and policy.

```erb
Set up your application secret and security options in `config/application.rb`:

```ruby
config.filestack_rails.app_secret = 'YOUR_APP_SECRET'
config.filestack_rails.security = {'call' => %w[pick store read convert] }
```
If you set security to an empty object like so
```erb
If you set security to an empty object like so:
```ruby
config.filestack_rails.security = {}
```
it will provide a policy and signature with only an expiry setting (this defaults to one hour).
It will provide a policy and signature with only an expiry setting (this defaults to one hour).

You can access the generated policy and signature anytime by calling their attributes on the created security object:

```erb
```ruby
puts config.filestack_rails.security.policy
puts config.filestack_rails.security.signature
```
You can also generate a new security object at any time, although this will only affect the filestack_image tag, and not the File Picker client.
You can also generate a new security object at any time, although this will only affect the filestack_image tag, and not the File Picker client.

## Usage

Filestack::Rails provides three main functionalities:

### Filestack Upload Button
This is a generic button that can be added anywhere in your application and opens an instance of the File Picker. Once a user has chosen a file(s) and submitted, a callback will be executed, passing in the results. You can also pass in any options for the File Picker using the pickerOptions symbol:
This is a generic button that can be added anywhere in your application and opens an instance of the File Picker. Once a user has chosen a file(s) and submitted, a callback will be executed, passing in the results. You can also pass in any options for the File Picker using the `pickerOptions` symbol:

```erb
<%= filestack_picker_element 'button test', 'callbackForButton', id: 'someuniequeid', pickerOptions: { 'fromSources' => 'facebook' } %>
<%= filestack_picker_element 'button test', 'callbackForButton', id: 'someuniqueid', input_id: 'someuniqueinputid', pickerOptions: { 'fromSources' => 'facebook' } %>
```
File Picker options are exactly the same as in the Javscript SDK and can be found in the aforementioned documentation.
File Picker options are exactly the same as in the Javscript SDK and can be found in the aforementioned documentation.

The callback can be either the name of a function you've defined in your main Javascript or it can be any code that is immediately executable, e.g. "console.log" or "(function(data){console.log(data)})". The callback should take in a response array as its only argument, which has the following structure:
The callback can be either the name of a function you've defined in your main Javascript or it can be any code that is immediately executable, e.g. `console.log` or `(function(data){console.log(data)})`. The callback should take in a response array as its only argument, which has the following structure:

```javascript
{
Expand Down Expand Up @@ -116,43 +132,48 @@ The form helper wraps the generic Pick element and adds the value of the returne
```erb
<%= form_for @user do |f| %>
<div>
<%= f.filestack_field :filepicker_url, 'Upload Your Avatar!', pickerOptions: {'fromSources': 'facebook'}, id: 'unique-id' %>
<%= f.filestack_field :filepicker_url, 'Upload Your Avatar!', pickerOptions: {'fromSources': 'facebook'}, id: 'unique-id', input_id: 'unique-input-id' %>
</div>

<%= f.submit %>
<% end %>
```
### Displaying an image with Filestack Transformations:
Filestack::Rails now has access to the full list of image transforms through our custom Transformation Engine. This functionality is provided by the Filestack Ruby SDK and acts as a small wrapper around it. The filestack_image tag accepts the same options as the genric Rails image_tag, with the addition of a transform option, which accepts a filestack_transform chain:
Filestack::Rails now has access to the full list of image transforms through our custom Transformation Engine. This functionality is provided by the Filestack Ruby SDK and acts as a small wrapper around it. The `filestack_image` tag accepts the same options as the genric Rails `image_tag`, with the addition of a transform option, which accepts a `filestack_transform` chain:

```erb
<%= filestack_image @user.filepicker_url, transform: filestack_transform.resize(width:100, height:100).flip.enhance %>
```
## Migrating from 2.x to 3.x
Filestack::Rails 3.x is a significant and breaking change. Users wishing to upgrade will need to change their current implementation in order to use the plugin correctly.
Filestack::Rails 3.x is a significant and breaking change. Users wishing to upgrade will need to change their current implementation in order to use the plugin correctly.

### Javascript-based File Picker
The v3 File Picker is a Javascript application that lives on the client-side of your application. This means you have greater control and access to when it is called, access to the rest of the web SDK, as well as being able to pass callbacks executed once uploads have completed. You must keep in mind the File Picker client lives in global scope and adjust your namespaces accordingly, although you can also change the name of the client, as detailed in the above sections.

### Form Helper
The form helper's call remains essentially the same, except that it now takes as its argument the value of the button element displayed on the page.
The form helper's call remains essentially the same, except that it now takes as its argument the value of the button element displayed on the page.
```erb
<%= f.filestack_field :filestack_url, 'Pick Your Avatar' >
```
### Save Button
As user saving/downloading is not currently supported in the v3 File Picker, that functionality has been removed from Filestack::Rails for the time being.
As user saving/downloading is not currently supported in the v3 File Picker, that functionality has been removed from Filestack::Rails for the time being.

### Transformations
The filestack_image tag wraps the generic Rails image_tag and generates a new URL with use of the Ruby SDK. This provides the entire scope of the possible transformations through Filestack's transformation engine, minus those which do not return an image (like debug, av_convert, and so forth). Defining transformations is as simple as chaining them together using the filestack_transform method:
The `filestack_image` tag wraps the generic Rails `image_tag` and generates a new URL with use of the Ruby SDK. This provides the entire scope of the possible transformations through Filestack's transformation engine, minus those which do not return an image (like debug, av_convert, and so forth). Defining transformations is as simple as chaining them together using the `filestack_transform` method:
```erb
<%= @user.filestack_url, transform: filestack_transform.resize(width:100, height:100).enhance %>
```

### Ruby SDK
Filestack::Rails injects the Filestack Ruby SDK into your application for use anywhere. You can use it to access the rest of the Filestack API and find its documentation [here](https://github.com/filestack/filestack-ruby)
Filestack::Rails injects the Filestack Ruby SDK into your application for use anywhere. You can use it to access the rest of the Filestack API and find its documentation [here](https://github.com/filestack/filestack-ruby).

## Demo

To see the Filestack::Rails plugin in action, clone this repository and run the demo app by following these instructions (will only work in Rails 5.x):
To see the Filestack::Rails plugin in action, clone this repository and run the demo app by following these instructions (will only work in Rails 5.x):

### Set API key

Go to ```spec/dummy/config/application.rb``` and change the API key to your own.
Go to ```spec/dummy/config/application.rb``` and change the API key to your own.

### Install Dependencies

Expand Down Expand Up @@ -183,20 +204,3 @@ Filestack::Rails follows the [Semantic Versioning](http://semver.org/).
## Issues

If you have problems, please create a [Github Issue](https://github.com/filepicker/filestack-rails/issues).

## Contributing

Please see [CONTRIBUTING.md](https://github.com/filepicker/filestack-rails/CONTRIBUTING.md) for details.

## Credits

Thank you to all the [contributors](https://github.com/filepicker/filestack-rails/graphs/contributors).

[gem_version_badge]: https://badge.fury.io/rb/filestack-rails.svg
[ruby_gems]: http://rubygems.org/gems/filestack-rails
[travis_ci]: http://travis-ci.org/filestack/filestack-rails
[travis_ci_badge]: https://travis-ci.org/filestack/filestack-rails.svg?branch=master
[code_climate]: https://codeclimate.com/github/filestack/filestack-rails
[code_climate_badge]: https://codeclimate.com/github/filestack/filestack-rails.png
[coveralls]: https://coveralls.io/github/filestack/filestack-rails?branch=master
[coveralls_badge]: https://coveralls.io/repos/github/filestack/filestack-rails/badge.svg?branch=master
21 changes: 13 additions & 8 deletions app/helpers/filestack_rails/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,8 @@ def filestack_js_include_tag

def filestack_js_init_tag
client_name, apikey = get_client_and_api_key
signature, policy = get_policy_and_signature
javascript_string = if policy && signature
"var #{client_name} = filestack.init('#{apikey}'," \
"{'signature': '#{signature}', 'policy': '#{policy}'});"
else
"var #{client_name} = filestack.init('#{apikey}');"
end
signature_and_policy = get_policy_and_signature_string
javascript_string = "var #{client_name} = filestack.init('#{apikey}', #{signature_and_policy}, '#{cname}');"
javascript_tag javascript_string
end

Expand All @@ -26,7 +21,7 @@ def filestack_picker_element(content, callback, options = {})
options[:onclick] = create_javascript_for_picker(callback, picker_options)
options[:type] = 'button'
button_tag content, options
end
end

def filestack_transform
_, apikey = get_client_and_api_key
Expand All @@ -46,6 +41,10 @@ def filestack_image(url, options = {})

private

def cname
::Rails.application.config.filestack_rails.cname
end

def create_javascript_for_picker(callback, options)
client_name, = get_client_and_api_key
json_string = if options.nil?
Expand Down Expand Up @@ -74,5 +73,11 @@ def get_policy_and_signature
end
return [signature, policy]
end

def get_policy_and_signature_string
signature, policy = get_policy_and_signature
return "{'signature': '#{signature}', 'policy': '#{policy}'}" if policy && signature
return "''"
end
end
end
8 changes: 6 additions & 2 deletions app/helpers/filestack_rails/form_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def filestack_field(method, content, options = {})

def get_filestack_field_button(method, content, options = {})
input_options = {}
input_options[:id] = "#{@object.class.name.downcase}_#{method.downcase}"
input_options[:id] = filestack_input_field_id(method, options[:input_id])
input_options[:style] = 'display:none'
user_callback = options[:callback] || nil
options.delete(:callback)
Expand All @@ -22,11 +22,15 @@ def get_filestack_field_button(method, content, options = {})
unless user_callback.nil?
form_field_callback_guts = "#{form_field_callback_guts}#{user_callback}(data)"
end

form_field_callback = "(function(data){#{form_field_callback_guts}})"

html_string = "#{filestack_picker_element(content, form_field_callback, options)}#{text_field(method, input_options)}"
raw html_string.html_safe
end

def filestack_input_field_id(method, input_id)
input_id.presence || "#{@object.class.name.downcase}_#{method.downcase}"
end
end
end
2 changes: 1 addition & 1 deletion filestack-rails.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Gem::Specification.new do |s|
s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"]

s.add_dependency 'rails', '>= 4.0'
s.add_dependency "filestack", "~> 2.1.0"
s.add_dependency "filestack", "~> 2.2.1"

s.add_development_dependency 'coveralls'
s.add_development_dependency 'sqlite3'
Expand Down
4 changes: 2 additions & 2 deletions lib/filestack_rails/configuration.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module FilestackRails
class Configuration
attr_accessor :api_key, :client_name, :secret_key, :security, :expiry, :app_secret
attr_accessor :api_key, :client_name, :secret_key, :security, :expiry, :app_secret, :cname

def api_key
@api_key or raise "Set config.filepicker_rails.api_key"
Expand All @@ -22,4 +22,4 @@ def security=(security_options = {})
end

end
end
end
6 changes: 3 additions & 3 deletions spec/helpers/application_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
end
end

describe "#filestack_picker_element" do
describe "#filestack_picker_element" do
it "has the right picker element" do
html_string = filestack_picker_element "hello!", "console.log('hello!')"
correct_string = '<button name="button" type="button" onclick="(function(){
Expand All @@ -38,9 +38,9 @@
end

describe "#filestack_image" do
it "returns the correct tag" do
it "returns the correct tag" do
image = filestack_image 'www.example.com', transform: filestack_transform.resize(width: 100, height: 100)
correct = '<img src="https://cdn.filestackcontent.com/API_KEY/resize=width:100,height:100/www.example.com" alt="Www.example" />'
correct = '<img src="https://cdn.filestackcontent.com/API_KEY/resize=width:100,height:100/www.example.com" />'
expect(image).to eq(correct)
end
end
Expand Down
18 changes: 17 additions & 1 deletion spec/helpers/form_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,26 @@
include FilestackRails::FormHelper
include ActionView::Helpers
describe '#filestack_field' do

it "provides the correct form_tag" do
output = filestack_field :picture, "some content"
expect(output).to include("<button")
expect(output).to include("</button>")
expect(output).to include("</button>")
end

it 'provides the default input id' do
@object = Object.new
output = filestack_field :picture, 'some content'
expect(output).to include('object_picture')
end

context 'when options input_id is set' do
let(:options) { {input_id: 'my_custom_id'} }

it 'provides the correct input_id' do
output = filestack_field :picture, 'some content', options
expect(output).to include('my_custom_id')
end
end
end
end
12 changes: 12 additions & 0 deletions spec/lib/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,16 @@
expect(configuration.security.signature)
end
end

describe '#cname' do
it 'has no cname' do
expect(configuration.cname).to be(nil)
end

it 'has cname' do
cname = 'fs.mycname.com'
configuration.cname = cname
expect(configuration.cname).to eq cname
end
end
end