Coder Social home page Coder Social logo

code-ops-show / transponder Goto Github PK

View Code? Open in Web Editor NEW
39.0 6.0 3.0 443 KB

Transponder is an opinionated gem for assisting in working with front end heavy rails app.

Home Page: https://github.com/codemy/transponder

License: MIT License

Ruby 55.73% CoffeeScript 40.31% JavaScript 1.48% Shell 0.23% HTML 2.25%

transponder's Introduction

Transponder

Build Status Gem Version Coverage Status Code Climate

Transponder Banner

Transponder is a opinionated library for assisting in working with front end heavy rails app.

8kb uncompressed / 2kb minified & compressed (gzip) (client side library)

Example App Using Transponder

Try opening the Kontax app in multiple browser and update something, and see how transponder's abstraction make this sort of thing very clean and easy for a rails app.

Installation

Add this line to your application's Gemfile:

gem 'transponder'

And then execute:

$ bundle

Or install it yourself as:

$ gem install transponder

Generate a basic Module

A transponder module provides some basic structure for your javascript code

rails g transponder:install application

This will generate a transponder 'module' in your app/assets/javascripts folder by the name of 'application', you can change the application to something else, but we recommend sticking with defaults until you understand more about transponder.

Generate a Presenter

Presenters is perhaps one of the most important thing about Transponder, it allows you to use your server side templates in your client side code, cleanly and allows better reuseability of code.

rails g transponder:presenter contacts

Running this command will generate a presenter in your Transponder module application/presenters with the name contacts_presenter.coffee

How is this better than Rails UJS?

Typically with Rails UJS you would create a view with something like this

Lets say you have a basic contacts_controller.rb

class ContactsController < ApplicationController
  respond_to :json, :html, :js

  def index
    @contacts = Contact.all
    respond_with @contacts
  end
end

In your index.js.erb you would then have something like this

$('#contacts').html("<%= j render @contacts %>");

This Javascript code is evaled in the browser and content of the node with the id #contacts gets replaced with server side template that came from <%= j render @contacts %> This is fine however it has a few problems. First of all if you use coffeescript it has to be compiled in real time as its responding which adds to your response time. Secondly if you want to do more complex things in your response things can get very messy. Code reuse isn't that great either.

With Transponder you have a consistent way of working with your server side template. Lets take a look at the difference

In your index.js.erb transponder version would look something like this.

["#contacts", "<%= xms_event %>", "<%= j render @contacts %>"]

Your server side response code using transponder will mostly likely look something like this. There is consistency to it. The first element is the DOM node you want to manipulate, the second element is what will allow the client side Transponder code to know which Presenter is responsible for this response and lastly we have the server side generated content.

So what happens once this response gets to the client

Well in our presenter we would do something like this

class Application.Presenters.ContactsPresenter extends Transponder.Presenter
  presenterName: 'contacts'
  module: 'application'

  index: ->
    $(@element).html(@response)
    # ... do more stuff ...

The first 3 lines of code are generated by the presenter generator you were just using before the only line of code you should pay attention to here is the last 2. Basically the @element is the dom element you specified in index.js.erb and the @response is the content that was rendered by the server.

In the presenter you can do pretty much anything you want to your response before it gets output to the DOM. This gives a nice structure and consistency to the whole pattern. It allows you to mix server side templates with full client side programmability.

Testing is also much easier as now you've shifted the responsibility of the client side behavior to the client. We have more documentation coming on how to test your presenters.

Services

Services are meant to be an easy way to manage functionality of a widget on a page. What does this mean?

Generally we will have elements on the page that do more than just display information, they have to listen to some even like a mouse click or a tap and then act on that. They may have 1 simple functionality or multiple functions Services are a way to manage that.

Services are designed to be idempotent. You can run a service on a page repeatedly and it will not apply to the widgets that already have the same service applied. This can be very useful when working with pages that use pjax / turbolinks / single page apps etc...

Service Generator

To generate a service simply type

rails g transponder:service contacts_search

In our initializers/manifest.coffee file we have something like this

Application.services_manifest = ->
  $('body').trigger 'application:services:contacts_search'

Basically we want to trigger this service on the page. Since we're using 'body' as the element the service will run on every page. If we apply a class to the html <body> tag to something like this in our application layout file <body class="<%= controller_name %> <%= action_name %>" we can trigger specific services on specific pages.

For example if we're on the controller index page and we want to trigger the contacts search only when we're on that page we can do something like this

Application.services_manifest = ->
  $('body.contacts.index').trigger 'application:services:contacts_search'

This gives us very fine grained control as to which services should run on which pages.

We have this in our erb some where on our page

<%= form_tag contacts_path, class: 'navbar-form navbar-left contacts_search', remote: true do %>
  <div class='form-group'>
    <%= text_field_tag :query, nil,class: 'form-control', placeholder: "Search for someone", id: 'search-field' %>
  </div>
<% end %>

which renders down to

<form accept-charset="UTF-8" action="/contacts" class="navbar-form navbar-left contacts_search contacts_search_active" data-remote="true" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="โœ“"></div>
  <div class="form-group">
    <input class="form-control" id="search-field" name="query" placeholder="Search for someone" type="text">
  </div>
</form>

The service will detect the element on the page with the matching class to the serviceName: and apply the behavior to those elements.

class Application.Services.ContactsSearch extends Transponder.Service
  serviceName: 'contacts_search'
  module: 'application'

  init: ->
    @element.on 'keyup', "#search-field", @submitSearch

  search: _.debounce ( (e) -> 
    field = @element.find('#search-field')
    $.ajax 
      url: @element.prop('action')
      dataType: 'script'
      data: 
        query: field.val()
  ), 600

  submitSearch: (field) =>
    @search(field)

  serve: ->
    @init()

TODO - Whats Coming

  • Add Documentation
  • Video Screencasts
  • Add more features to Kontax
  • More documentation on Services

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Credits

Gem developed by Zack Siri of Artellectual

Bitdeli Badge

transponder's People

Contributors

bitdeli-chef avatar zacksiri 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

transponder's Issues

Docs

hi, is this project active ? can you provide any documentation or write more about usage ? seems cool, cheers

License missing from gemspec

RubyGems.org doesn't report a license for your gem. This is because it is not specified in the gemspec of your last release.

via e.g.

spec.license = 'MIT'
# or
spec.licenses = ['MIT', 'GPL-2']

Including a license in your gemspec is an easy way for rubygems.org and other tools to check how your gem is licensed. As you can imagine, scanning your repository for a LICENSE file or parsing the README, and then attempting to identify the license or licenses is much more difficult and more error prone. So, even for projects that already specify a license, including a license in your gemspec is a good practice. See, for example, how rubygems.org uses the gemspec to display the rails gem license.

There is even a License Finder gem to help companies/individuals ensure all gems they use meet their licensing needs. This tool depends on license information being available in the gemspec. This is an important enough issue that even Bundler now generates gems with a default 'MIT' license.

I hope you'll consider specifying a license in your gemspec. If not, please just close the issue with a nice message. In either case, I'll follow up. Thanks for your time!

Appendix:

If you need help choosing a license (sorry, I haven't checked your readme or looked for a license file), GitHub has created a license picker tool. Code without a license specified defaults to 'All rights reserved'-- denying others all rights to use of the code.
Here's a list of the license names I've found and their frequencies

p.s. In case you're wondering how I found you and why I made this issue, it's because I'm collecting stats on gems (I was originally looking for download data) and decided to collect license metadata,too, and make issues for gemspecs not specifying a license as a public service :). See the previous link or my blog post about this project for more information.

service generator

the service generator will do all the tedious work for generating the service for the specified app

presenter generator

the presenter generator will do all the tedious work in setting up the generator for the specified app.

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.