inplace_i18n 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +16 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +93 -0
- data/LICENSE +20 -0
- data/README.md +66 -0
- data/app/assets/javascripts/inplace_i18n/inplace_i18n.js.coffee.erb +50 -0
- data/app/assets/stylesheets/inplace_i18n/inplace_i18n_styles.sass +64 -0
- data/app/controllers/inplace_i18n/translations_controller.rb +25 -0
- data/app/model/inplace_i18n/translation.rb +58 -0
- data/app/views/inplace_i18n/_js.erb +1 -0
- data/app/views/inplace_i18n/_styles.erb +1 -0
- data/config/routes.rb +4 -0
- data/inplace_i18n.gemspec +22 -0
- data/lib/inplace_i18n.rb +5 -0
- data/lib/inplace_i18n/engine.rb +22 -0
- data/lib/inplace_i18n/hash_tools.rb +100 -0
- data/lib/inplace_i18n/helpers/action_view.rb +17 -0
- data/lib/inplace_i18n/translation_helper.rb +27 -0
- data/lib/inplace_i18n/version.rb +3 -0
- data/lib/tasks/inplace_i18n_tasks.rake +4 -0
- metadata +98 -0
    
        data/.gitignore
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/Gemfile.lock
    ADDED
    
    | @@ -0,0 +1,93 @@ | |
| 1 | 
            +
            PATH
         | 
| 2 | 
            +
              remote: .
         | 
| 3 | 
            +
              specs:
         | 
| 4 | 
            +
                inplace_i18n (0.0.1)
         | 
| 5 | 
            +
                  ya2yaml
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            GEM
         | 
| 8 | 
            +
              remote: http://rubygems.org/
         | 
| 9 | 
            +
              specs:
         | 
| 10 | 
            +
                actionmailer (3.2.3)
         | 
| 11 | 
            +
                  actionpack (= 3.2.3)
         | 
| 12 | 
            +
                  mail (~> 2.4.4)
         | 
| 13 | 
            +
                actionpack (3.2.3)
         | 
| 14 | 
            +
                  activemodel (= 3.2.3)
         | 
| 15 | 
            +
                  activesupport (= 3.2.3)
         | 
| 16 | 
            +
                  builder (~> 3.0.0)
         | 
| 17 | 
            +
                  erubis (~> 2.7.0)
         | 
| 18 | 
            +
                  journey (~> 1.0.1)
         | 
| 19 | 
            +
                  rack (~> 1.4.0)
         | 
| 20 | 
            +
                  rack-cache (~> 1.2)
         | 
| 21 | 
            +
                  rack-test (~> 0.6.1)
         | 
| 22 | 
            +
                  sprockets (~> 2.1.2)
         | 
| 23 | 
            +
                activemodel (3.2.3)
         | 
| 24 | 
            +
                  activesupport (= 3.2.3)
         | 
| 25 | 
            +
                  builder (~> 3.0.0)
         | 
| 26 | 
            +
                activerecord (3.2.3)
         | 
| 27 | 
            +
                  activemodel (= 3.2.3)
         | 
| 28 | 
            +
                  activesupport (= 3.2.3)
         | 
| 29 | 
            +
                  arel (~> 3.0.2)
         | 
| 30 | 
            +
                  tzinfo (~> 0.3.29)
         | 
| 31 | 
            +
                activeresource (3.2.3)
         | 
| 32 | 
            +
                  activemodel (= 3.2.3)
         | 
| 33 | 
            +
                  activesupport (= 3.2.3)
         | 
| 34 | 
            +
                activesupport (3.2.3)
         | 
| 35 | 
            +
                  i18n (~> 0.6)
         | 
| 36 | 
            +
                  multi_json (~> 1.0)
         | 
| 37 | 
            +
                arel (3.0.2)
         | 
| 38 | 
            +
                builder (3.0.0)
         | 
| 39 | 
            +
                erubis (2.7.0)
         | 
| 40 | 
            +
                hike (1.2.1)
         | 
| 41 | 
            +
                i18n (0.6.0)
         | 
| 42 | 
            +
                journey (1.0.3)
         | 
| 43 | 
            +
                json (1.7.1)
         | 
| 44 | 
            +
                mail (2.4.4)
         | 
| 45 | 
            +
                  i18n (>= 0.4.0)
         | 
| 46 | 
            +
                  mime-types (~> 1.16)
         | 
| 47 | 
            +
                  treetop (~> 1.4.8)
         | 
| 48 | 
            +
                mime-types (1.18)
         | 
| 49 | 
            +
                multi_json (1.3.4)
         | 
| 50 | 
            +
                polyglot (0.3.3)
         | 
| 51 | 
            +
                rack (1.4.1)
         | 
| 52 | 
            +
                rack-cache (1.2)
         | 
| 53 | 
            +
                  rack (>= 0.4)
         | 
| 54 | 
            +
                rack-ssl (1.3.2)
         | 
| 55 | 
            +
                  rack
         | 
| 56 | 
            +
                rack-test (0.6.1)
         | 
| 57 | 
            +
                  rack (>= 1.0)
         | 
| 58 | 
            +
                rails (3.2.3)
         | 
| 59 | 
            +
                  actionmailer (= 3.2.3)
         | 
| 60 | 
            +
                  actionpack (= 3.2.3)
         | 
| 61 | 
            +
                  activerecord (= 3.2.3)
         | 
| 62 | 
            +
                  activeresource (= 3.2.3)
         | 
| 63 | 
            +
                  activesupport (= 3.2.3)
         | 
| 64 | 
            +
                  bundler (~> 1.0)
         | 
| 65 | 
            +
                  railties (= 3.2.3)
         | 
| 66 | 
            +
                railties (3.2.3)
         | 
| 67 | 
            +
                  actionpack (= 3.2.3)
         | 
| 68 | 
            +
                  activesupport (= 3.2.3)
         | 
| 69 | 
            +
                  rack-ssl (~> 1.3.2)
         | 
| 70 | 
            +
                  rake (>= 0.8.7)
         | 
| 71 | 
            +
                  rdoc (~> 3.4)
         | 
| 72 | 
            +
                  thor (~> 0.14.6)
         | 
| 73 | 
            +
                rake (0.9.2.2)
         | 
| 74 | 
            +
                rdoc (3.12)
         | 
| 75 | 
            +
                  json (~> 1.4)
         | 
| 76 | 
            +
                sprockets (2.1.3)
         | 
| 77 | 
            +
                  hike (~> 1.2)
         | 
| 78 | 
            +
                  rack (~> 1.0)
         | 
| 79 | 
            +
                  tilt (~> 1.1, != 1.3.0)
         | 
| 80 | 
            +
                thor (0.14.6)
         | 
| 81 | 
            +
                tilt (1.3.3)
         | 
| 82 | 
            +
                treetop (1.4.10)
         | 
| 83 | 
            +
                  polyglot
         | 
| 84 | 
            +
                  polyglot (>= 0.3.1)
         | 
| 85 | 
            +
                tzinfo (0.3.33)
         | 
| 86 | 
            +
                ya2yaml (0.31)
         | 
| 87 | 
            +
             | 
| 88 | 
            +
            PLATFORMS
         | 
| 89 | 
            +
              ruby
         | 
| 90 | 
            +
             | 
| 91 | 
            +
            DEPENDENCIES
         | 
| 92 | 
            +
              inplace_i18n!
         | 
| 93 | 
            +
              rails (= 3.2.3)
         | 
    
        data/LICENSE
    ADDED
    
    | @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            Copyright (c) 2011 Gregory Tangey
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Permission is hereby granted, free of charge, to any person obtaining
         | 
| 4 | 
            +
            a copy of this software and associated documentation files (the
         | 
| 5 | 
            +
            "Software"), to deal in the Software without restriction, including
         | 
| 6 | 
            +
            without limitation the rights to use, copy, modify, merge, publish,
         | 
| 7 | 
            +
            distribute, sublicense, and/or sell copies of the Software, and to
         | 
| 8 | 
            +
            permit persons to whom the Software is furnished to do so, subject to
         | 
| 9 | 
            +
            the following conditions:
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            The above copyright notice and this permission notice shall be
         | 
| 12 | 
            +
            included in all copies or substantial portions of the Software.
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         | 
| 15 | 
            +
            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 16 | 
            +
            MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         | 
| 17 | 
            +
            NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         | 
| 18 | 
            +
            LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         | 
| 19 | 
            +
            OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         | 
| 20 | 
            +
            WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         | 
    
        data/README.md
    ADDED
    
    | @@ -0,0 +1,66 @@ | |
| 1 | 
            +
            # inplace_i18n
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            ## About
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Add/Edit Translations inside your application by using this gem and mounting its rails engine.
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            It makes a few assumptions:
         | 
| 8 | 
            +
            * you use **yaml for translations**
         | 
| 9 | 
            +
            * your **translations are stored in [locale].yml**
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            It does a few things you might not like:
         | 
| 12 | 
            +
            * it re-arranges your [locale].yml alphabetically by key
         | 
| 13 | 
            +
            * there's ZERO security, anyone can and will play with your translations. Don't be a production dummy.
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            ## Why?
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            I hate trawling through translation files.
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            ## Usage
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            Using inplace_i18n with rails is pretty straight forward, drop this into your Gemfile:
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                group :development do
         | 
| 24 | 
            +
                  gem 'inplace_i18n', git: 'git://github.com/Ruxton/inplace_i18n.git'
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            Then add the javascript and stylesheets to your project, there are 2 helper methods for this.  In your head place the stylesheet:
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                %head
         | 
| 30 | 
            +
                  = inplace_i18n_stylesheets
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            And wherever you put your javascript:
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                = inplace_i18n_js
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            Alternatively you can add them to your existing assets using the asset pipeline:
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                @import inplace_i18n/inplace_i18n_styles
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            and:
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                #= require inplace_i18n/inplace_i18n
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            Finally, mount the engine somewhere in your applications config/routes.rb file:
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                mount InplaceI18n::Engine => '/translate'
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            An 'Edit Translations' button will show up in the top right hand corner of your site, clicking it will overlay pencil icons above every translation.  Clicking on the pencil will allow you to edit that translation.
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            If you have translations inside the attributes of a HTML Element, pass inplace: false as an option to the translation and the editor wont be added for that translation.  Currently adding it these will cause your HTML to break.
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                image_tag 'awesome-image.png', alt: t('.awesome_image_alt', inplace: false)
         | 
| 53 | 
            +
             | 
| 54 | 
            +
             | 
| 55 | 
            +
            ## Thanks, Kudos & Legalities
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            * Implementation idea & some code adopted from [i18n_locale_editor](http://github.com/n1k/i18n_locale_editor/)
         | 
| 58 | 
            +
            * Edit icon c/o [FamFam Silk Iconset](http://www.famfamfam.com/lab/icons/silk/)
         | 
| 59 | 
            +
             | 
| 60 | 
            +
            ## Copyright
         | 
| 61 | 
            +
             | 
| 62 | 
            +
            Copyright (c) 2011 [Gregory Tangey](http://ignite.digitalignition.net/). See LICENSE for details.
         | 
| 63 | 
            +
             | 
| 64 | 
            +
             | 
| 65 | 
            +
             | 
| 66 | 
            +
             | 
| @@ -0,0 +1,50 @@ | |
| 1 | 
            +
            jQuery ($) ->
         | 
| 2 | 
            +
              addTranslationButton()
         | 
| 3 | 
            +
              registerTranslationClick()
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            addTranslationButton = () ->
         | 
| 6 | 
            +
              $('body').append '<div id="inplace_i18n">Edit Translations</div>'
         | 
| 7 | 
            +
              target = $('#inplace_i18n')
         | 
| 8 | 
            +
              target.on 'click', (e) ->
         | 
| 9 | 
            +
                e.preventDefault
         | 
| 10 | 
            +
                $('span.inplace_i18n').toggle()
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            inplaceI18nUrl = (key) ->
         | 
| 13 | 
            +
              <%
         | 
| 14 | 
            +
                path = InplaceI18n::Engine.routes.url_helpers.translation_path('1')
         | 
| 15 | 
            +
              %>
         | 
| 16 | 
            +
              url = '<%= path %>'
         | 
| 17 | 
            +
              url = url.replace('/1','/'+key)
         | 
| 18 | 
            +
              return url
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            updateTranslation = (key,value) ->
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              url = inplaceI18nUrl(key)
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              if value? and key?
         | 
| 25 | 
            +
                request = $.ajax
         | 
| 26 | 
            +
                  type: "PUT"
         | 
| 27 | 
            +
                  url: url
         | 
| 28 | 
            +
                  data:
         | 
| 29 | 
            +
                    value: value
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  async: true
         | 
| 32 | 
            +
                  success: ->
         | 
| 33 | 
            +
                    console.log 'Success'
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  error: ->
         | 
| 36 | 
            +
                    alert "error posting data to url:" + url
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            registerTranslationClick = () ->
         | 
| 39 | 
            +
              $('span.inplace_i18n').on 'click', (e) ->
         | 
| 40 | 
            +
                e.preventDefault()
         | 
| 41 | 
            +
                key = e.srcElement.id
         | 
| 42 | 
            +
                url = inplaceI18nUrl(key)
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                request = $.ajax
         | 
| 45 | 
            +
                  type: "GET"
         | 
| 46 | 
            +
                  url: url
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                request.success (msg) ->
         | 
| 49 | 
            +
                  a = prompt('Translation',request.responseText)
         | 
| 50 | 
            +
                  updateTranslation(key,a)
         | 
| @@ -0,0 +1,64 @@ | |
| 1 | 
            +
            .i18n_translation
         | 
| 2 | 
            +
              position: relative
         | 
| 3 | 
            +
              width: 0px
         | 
| 4 | 
            +
              height: 0px
         | 
| 5 | 
            +
              .inplace_i18n
         | 
| 6 | 
            +
                display: none
         | 
| 7 | 
            +
                width: 16px
         | 
| 8 | 
            +
                height: 16px
         | 
| 9 | 
            +
                position: absolute
         | 
| 10 | 
            +
                top: -20px
         | 
| 11 | 
            +
                right: -20px
         | 
| 12 | 
            +
                z-index: 99999999
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                background: #e3e3e3
         | 
| 15 | 
            +
                background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAFUSURBVDjLrZM/SAJxGIZdWwuDlnCplkAEm1zkaIiGFFpyMIwGK5KGoK2lphDKkMDg3LLUSIJsSKhIi+684CokOtTiMizCGuzEU5K3vOEgKvtBDe/2Pc8H3x8NAM1fQlx4H9M3pcOWp6TXWmM8A7j0629v1nraiAVC0IrrwATKIgs5xyG5QiE+Z4iQdoeU2oAsnqCSO1NSTu+D9VhqRLD8nIB8F0Q2MgmJDyipCzjvYJkIfpN2UBLG8MpP4dxvQ3ZzGuyyBQ2H+AnOOCBd9aL6soh81A5hyYSGWyCFvxUcerqI4S+CvYVOFPMHxLAq8I3qdHVY5LbBhJzEsCrwutpRFBlUHy6wO2tEYtWAzLELPN2P03kjfj3luqDycV2F8AgefWbEnVqEHa2IznSD6BdsVDNStB0lfh0FPoQjdx8RrAqGzC0YprSgxzsUMOY2bf37N/6Ud1Vc9yYcH50CAAAAAElFTkSuQmCC)
         | 
| 16 | 
            +
                border: 1px solid #bbb
         | 
| 17 | 
            +
                -webkit-border-radius: 3px
         | 
| 18 | 
            +
                -moz-border-radius: 3px
         | 
| 19 | 
            +
                border-radius: 3px
         | 
| 20 | 
            +
                -webkit-box-shadow: inset 0 0 1px 1px #f6f6f6
         | 
| 21 | 
            +
                -moz-box-shadow: inset 0 0 1px 1px #f6f6f6
         | 
| 22 | 
            +
                box-shadow: inset 0 0 1px 1px #f6f6f6
         | 
| 23 | 
            +
                color: #333
         | 
| 24 | 
            +
                font: bold 12px "helvetica neue", helvetica, arial, sans-serif
         | 
| 25 | 
            +
                height: 16px
         | 
| 26 | 
            +
                width: 16px
         | 
| 27 | 
            +
                text-align: center
         | 
| 28 | 
            +
                text-shadow: 0 1px 0 #fff
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            #inplace_i18n
         | 
| 31 | 
            +
              position: absolute
         | 
| 32 | 
            +
              top: 10px
         | 
| 33 | 
            +
              right: 20px
         | 
| 34 | 
            +
              display: block
         | 
| 35 | 
            +
              z-index: 99999999
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              background: #e3e3e3
         | 
| 38 | 
            +
              border: 1px solid #bbb
         | 
| 39 | 
            +
              -webkit-border-radius: 3px
         | 
| 40 | 
            +
              -moz-border-radius: 3px
         | 
| 41 | 
            +
              border-radius: 3px
         | 
| 42 | 
            +
              -webkit-box-shadow: inset 0 0 1px 1px #f6f6f6
         | 
| 43 | 
            +
              -moz-box-shadow: inset 0 0 1px 1px #f6f6f6
         | 
| 44 | 
            +
              box-shadow: inset 0 0 1px 1px #f6f6f6
         | 
| 45 | 
            +
              color: #333
         | 
| 46 | 
            +
              font: bold 12px "helvetica neue", helvetica, arial, sans-serif
         | 
| 47 | 
            +
              line-height: 1
         | 
| 48 | 
            +
              padding: 8px 0 9px
         | 
| 49 | 
            +
              text-align: center
         | 
| 50 | 
            +
              text-shadow: 0 1px 0 #fff
         | 
| 51 | 
            +
              width: 150px
         | 
| 52 | 
            +
              &:hover
         | 
| 53 | 
            +
                background: #d9d9d9
         | 
| 54 | 
            +
                -webkit-box-shadow: inset 0 0 1px 1px #eaeaea
         | 
| 55 | 
            +
                -moz-box-shadow: inset 0 0 1px 1px #eaeaea
         | 
| 56 | 
            +
                box-shadow: inset 0 0 1px 1px #eaeaea
         | 
| 57 | 
            +
                color: #222
         | 
| 58 | 
            +
                cursor: pointer
         | 
| 59 | 
            +
              &:active
         | 
| 60 | 
            +
                background: #d0d0d0
         | 
| 61 | 
            +
                -webkit-box-shadow: inset 0 0 1px 1px #e3e3e3
         | 
| 62 | 
            +
                -moz-box-shadow: inset 0 0 1px 1px #e3e3e3
         | 
| 63 | 
            +
                box-shadow: inset 0 0 1px 1px #e3e3e3
         | 
| 64 | 
            +
                color: #000
         | 
| @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            module InplaceI18n
         | 
| 2 | 
            +
              class TranslationsController < ApplicationController
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                before_filter :set_language
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                def show
         | 
| 7 | 
            +
                  value = Translation.all(@language).find_by_path(params[:path])
         | 
| 8 | 
            +
                  render :text => value
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                def update
         | 
| 12 | 
            +
                  Translation.update_by_path(@language, params[:path], params[:value])
         | 
| 13 | 
            +
                  I18n.reload!
         | 
| 14 | 
            +
                  render :text => "OK"
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                private
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def set_language
         | 
| 20 | 
            +
                  @language = params[:path].split(".").first if not params[:path].nil?
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            end
         | 
| @@ -0,0 +1,58 @@ | |
| 1 | 
            +
            require 'rubygems'
         | 
| 2 | 
            +
            require 'ya2yaml'
         | 
| 3 | 
            +
            require 'fileutils'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            class InplaceI18n::Translation
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              def self.all(locale)
         | 
| 8 | 
            +
                locale = locale.to_s
         | 
| 9 | 
            +
                file = File.join(Rails.root, "config/locales","#{locale}.yml")
         | 
| 10 | 
            +
                hash = YAML::load_file file
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              def self.update_by_path(locale,path,value)
         | 
| 14 | 
            +
                locale = locale.to_s
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                file = File.join(Rails.root, "config/locales","#{locale}.yml")
         | 
| 17 | 
            +
                hash = YAML::load_file file
         | 
| 18 | 
            +
                hash.update_by_path(path,value)
         | 
| 19 | 
            +
                File.open(file + ".new",'w') do |f|
         | 
| 20 | 
            +
                    f.puts hash.ya2yaml
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
                FileUtils.mv(file + ".new", file)
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              def self.merge_locales locales_array, only_missing = false
         | 
| 26 | 
            +
                #available_locales = I18n.available_locales.map{|loc| loc.to_s}
         | 
| 27 | 
            +
                #locales_array.each{|loc| raise "#{loc} locale not found" if not available_locales.include? loc.to_s }
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                paths = []
         | 
| 30 | 
            +
                translations = {}
         | 
| 31 | 
            +
                locales_array.each do |locale|
         | 
| 32 | 
            +
                  translations[locale] = translation = Translation.all(locale)
         | 
| 33 | 
            +
                  paths = paths + translation.paths.map{|path| path.gsub(/^#{locale.to_s}\./,"")}
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
                paths = paths.uniq
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                aggreg = {}
         | 
| 38 | 
            +
                paths.each do |path|
         | 
| 39 | 
            +
                  aggreg[path] = {}
         | 
| 40 | 
            +
                  locales_array.each do |locale|
         | 
| 41 | 
            +
                    aggreg[path][locale] = translations[locale].find_by_path(locale.to_s + '.' + path)
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
                if only_missing
         | 
| 45 | 
            +
                  return aggreg.delete_if do |path,translation|
         | 
| 46 | 
            +
                    ret = true
         | 
| 47 | 
            +
                    translation.each do |language, value|
         | 
| 48 | 
            +
                       ret = false if value.blank?
         | 
| 49 | 
            +
                    end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                    ret
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
                else
         | 
| 54 | 
            +
                  return aggreg
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              end
         | 
| 58 | 
            +
            end
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            <%= javascript_include_tag 'inplace_i18n/inplace_i18n' %>
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            <%= stylesheet_link_tag 'inplace_i18n/inplace_i18n_styles' %>
         | 
    
        data/config/routes.rb
    ADDED
    
    | @@ -0,0 +1,4 @@ | |
| 1 | 
            +
            InplaceI18n::Engine.routes.draw do
         | 
| 2 | 
            +
              put '/translations/:path', as: :translation, controller: :translations, to: :update, :constraints => { :path => /[\w.]+?/, format: false }
         | 
| 3 | 
            +
              get '/translations/:path', as: :translation, controller: :translations, to: :show, :constraints => { :path => /[\w.]+?/ , format: false }
         | 
| 4 | 
            +
            end
         | 
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            $:.push File.expand_path("../lib", __FILE__)
         | 
| 2 | 
            +
            require "inplace_i18n/version"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            Gem::Specification.new do |s|
         | 
| 5 | 
            +
              s.name = "inplace_i18n"
         | 
| 6 | 
            +
              s.summary = "Inplace editing for rails i18n."
         | 
| 7 | 
            +
              s.description = "inplace_i18n is an Engine that provides Inplace editing for rails i18n."
         | 
| 8 | 
            +
              s.version = InplaceI18n::VERSION
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              s.authors     = ["Ruxton"]
         | 
| 11 | 
            +
              s.email       = ["ruxton@thefrontiergroup.com.au"]
         | 
| 12 | 
            +
              s.homepage    = "http://ignite.digitalignition.net/"
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              s.files         = `git ls-files`.split("\n")
         | 
| 15 | 
            +
              s.test_files    = `git ls-files -- {test,spec,features}/*`.split("\n")
         | 
| 16 | 
            +
              s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
         | 
| 17 | 
            +
              s.require_paths = ["lib"]
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              s.rubyforge_project = "inplace_i18n"
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              s.add_dependency "ya2yaml"
         | 
| 22 | 
            +
            end
         | 
    
        data/lib/inplace_i18n.rb
    ADDED
    
    
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            require 'inplace_i18n'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module InplaceI18n
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              class Engine < ::Rails::Engine
         | 
| 6 | 
            +
                isolate_namespace InplaceI18n
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                require 'inplace_i18n/hash_tools'
         | 
| 9 | 
            +
                Hash.send :include, InplaceI18n::HashTools
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                initializer 'inplace_i18n.register_view_helper' do
         | 
| 12 | 
            +
                  require 'inplace_i18n/helpers/action_view'
         | 
| 13 | 
            +
                  ActionView::Base.send :include, InplaceI18n::Helpers::ActionView
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                initializer "inplace_i18n.install_translation_helper", after: 'i18n.callbacks'  do
         | 
| 17 | 
            +
                  require 'inplace_i18n/translation_helper'
         | 
| 18 | 
            +
                  ActionView::Helpers::TranslationHelper.send :include, InplaceI18n::TranslationHelper
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            end
         | 
| @@ -0,0 +1,100 @@ | |
| 1 | 
            +
            module InplaceI18n
         | 
| 2 | 
            +
              module HashTools
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                def find_by_path(path)
         | 
| 5 | 
            +
                  e ="self"
         | 
| 6 | 
            +
                  path_to_a(path).each{|i| e = e+"['"+ escape_for_eval(i)+ "']" }
         | 
| 7 | 
            +
                  begin
         | 
| 8 | 
            +
                    eval(e)
         | 
| 9 | 
            +
                  rescue NoMethodError
         | 
| 10 | 
            +
                    return nil
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def update_by_path(path, string)
         | 
| 15 | 
            +
                  return false if find_by_path(path).class == "Hash"
         | 
| 16 | 
            +
                  create_path_if_not_exist(path)
         | 
| 17 | 
            +
                  e ="self"
         | 
| 18 | 
            +
                  path_a = path_to_a(path)
         | 
| 19 | 
            +
                  path_a.each{|i| e = e+"['"+escape_for_eval(i)+"']" }
         | 
| 20 | 
            +
                  string = string.gsub(/^[ \t]+/,"")
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  string = escape_for_eval(string)
         | 
| 23 | 
            +
                  e = e+"='"+string+"'"
         | 
| 24 | 
            +
                  begin
         | 
| 25 | 
            +
                    eval(e)
         | 
| 26 | 
            +
                    return true
         | 
| 27 | 
            +
                  rescue => e
         | 
| 28 | 
            +
                    return [false, e]
         | 
| 29 | 
            +
                 end
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                def update_by_path_wo_parents(path, string)
         | 
| 33 | 
            +
                  return false if find_by_path(path).class.to_s == "Hash" && find_by_path(path).length > 0
         | 
| 34 | 
            +
                  e ="self"
         | 
| 35 | 
            +
                  path_a = path_to_a(path)
         | 
| 36 | 
            +
                  path_a.each{|i| e = e+"['"+ escape_for_eval(i)+"']" }
         | 
| 37 | 
            +
                  string = escape_for_eval(string)
         | 
| 38 | 
            +
                  e = e+"="+string.inspect+""
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  begin
         | 
| 41 | 
            +
                    eval(e)
         | 
| 42 | 
            +
                    return true
         | 
| 43 | 
            +
                  rescue
         | 
| 44 | 
            +
                    return false
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                def create_empty_node(path)
         | 
| 49 | 
            +
                  return false if not find_by_path(path).nil?
         | 
| 50 | 
            +
                  update_by_path_wo_parents(path, {})
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                def create_path_if_not_exist(path)
         | 
| 54 | 
            +
                  aa = path_to_a(path)
         | 
| 55 | 
            +
                  new_aa = []
         | 
| 56 | 
            +
                  aa.each do |a|
         | 
| 57 | 
            +
                    new_aa << a
         | 
| 58 | 
            +
                    create_empty_node(a_to_path(new_aa))
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                def nodes_array(path = [])
         | 
| 63 | 
            +
                  ret = []
         | 
| 64 | 
            +
                  self.each do |key,value|
         | 
| 65 | 
            +
                    if value.class == Hash
         | 
| 66 | 
            +
                      ret = ret + value.nodes_array(path + [key])
         | 
| 67 | 
            +
                    else
         | 
| 68 | 
            +
                      ret << path + [key]
         | 
| 69 | 
            +
                    end
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
                  ret
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                def next_path(path)
         | 
| 75 | 
            +
                  paths = self.paths
         | 
| 76 | 
            +
                  paths[paths.index(path) + 1]
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                def previous_path(path)
         | 
| 80 | 
            +
                  paths = self.paths
         | 
| 81 | 
            +
                  paths[paths.index(path) - 1]
         | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                private
         | 
| 85 | 
            +
                def path_to_a(string)
         | 
| 86 | 
            +
                  string.split(".")
         | 
| 87 | 
            +
                end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                def a_to_path(array)
         | 
| 90 | 
            +
                  array.join(".")
         | 
| 91 | 
            +
                end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                def escape_for_eval(string)
         | 
| 94 | 
            +
                  string.gsub!("'", "\\\\'") if string.class == String
         | 
| 95 | 
            +
                  string
         | 
| 96 | 
            +
                end
         | 
| 97 | 
            +
              end
         | 
| 98 | 
            +
            end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
            Hash.send(:include, InplaceI18n::HashTools)
         | 
| @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            module InplaceI18n
         | 
| 2 | 
            +
              module TranslationHelper
         | 
| 3 | 
            +
                extend ActiveSupport::Concern
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                included do
         | 
| 6 | 
            +
                  alias_method_chain :translate, :inplace_editing
         | 
| 7 | 
            +
                  alias :t :translate_with_inplace_editing
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def translate_with_inplace_editing(key, options = {})
         | 
| 11 | 
            +
                  key = scope_key_by_partial(key).to_s
         | 
| 12 | 
            +
                  inplace = true
         | 
| 13 | 
            +
                  inplace = options[:inplace] unless options.blank?
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  translation = translate_without_inplace_editing(key, options)
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  if inplace
         | 
| 18 | 
            +
                    key = I18n.locale.to_s + '.'+key
         | 
| 19 | 
            +
                    translation = " " if translation.blank?
         | 
| 20 | 
            +
                    translation = '<span class="i18n_translation"><span id="'+key+'" class="inplace_i18n"></span></span>' + translation
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  translation.html_safe
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
            end
         | 
    
        metadata
    ADDED
    
    | @@ -0,0 +1,98 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification 
         | 
| 2 | 
            +
            name: inplace_i18n
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            +
              hash: 29
         | 
| 5 | 
            +
              prerelease: 
         | 
| 6 | 
            +
              segments: 
         | 
| 7 | 
            +
              - 0
         | 
| 8 | 
            +
              - 0
         | 
| 9 | 
            +
              - 1
         | 
| 10 | 
            +
              version: 0.0.1
         | 
| 11 | 
            +
            platform: ruby
         | 
| 12 | 
            +
            authors: 
         | 
| 13 | 
            +
            - Ruxton
         | 
| 14 | 
            +
            autorequire: 
         | 
| 15 | 
            +
            bindir: bin
         | 
| 16 | 
            +
            cert_chain: []
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            date: 2012-05-10 00:00:00 Z
         | 
| 19 | 
            +
            dependencies: 
         | 
| 20 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 21 | 
            +
              name: ya2yaml
         | 
| 22 | 
            +
              prerelease: false
         | 
| 23 | 
            +
              requirement: &id001 !ruby/object:Gem::Requirement 
         | 
| 24 | 
            +
                none: false
         | 
| 25 | 
            +
                requirements: 
         | 
| 26 | 
            +
                - - ">="
         | 
| 27 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 28 | 
            +
                    hash: 3
         | 
| 29 | 
            +
                    segments: 
         | 
| 30 | 
            +
                    - 0
         | 
| 31 | 
            +
                    version: "0"
         | 
| 32 | 
            +
              type: :runtime
         | 
| 33 | 
            +
              version_requirements: *id001
         | 
| 34 | 
            +
            description: inplace_i18n is an Engine that provides Inplace editing for rails i18n.
         | 
| 35 | 
            +
            email: 
         | 
| 36 | 
            +
            - ruxton@thefrontiergroup.com.au
         | 
| 37 | 
            +
            executables: []
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            extensions: []
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            extra_rdoc_files: []
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            files: 
         | 
| 44 | 
            +
            - .gitignore
         | 
| 45 | 
            +
            - Gemfile
         | 
| 46 | 
            +
            - Gemfile.lock
         | 
| 47 | 
            +
            - LICENSE
         | 
| 48 | 
            +
            - README.md
         | 
| 49 | 
            +
            - app/assets/javascripts/inplace_i18n/inplace_i18n.js.coffee.erb
         | 
| 50 | 
            +
            - app/assets/stylesheets/inplace_i18n/inplace_i18n_styles.sass
         | 
| 51 | 
            +
            - app/controllers/inplace_i18n/translations_controller.rb
         | 
| 52 | 
            +
            - app/model/inplace_i18n/translation.rb
         | 
| 53 | 
            +
            - app/views/inplace_i18n/_js.erb
         | 
| 54 | 
            +
            - app/views/inplace_i18n/_styles.erb
         | 
| 55 | 
            +
            - config/routes.rb
         | 
| 56 | 
            +
            - inplace_i18n.gemspec
         | 
| 57 | 
            +
            - lib/inplace_i18n.rb
         | 
| 58 | 
            +
            - lib/inplace_i18n/engine.rb
         | 
| 59 | 
            +
            - lib/inplace_i18n/hash_tools.rb
         | 
| 60 | 
            +
            - lib/inplace_i18n/helpers/action_view.rb
         | 
| 61 | 
            +
            - lib/inplace_i18n/translation_helper.rb
         | 
| 62 | 
            +
            - lib/inplace_i18n/version.rb
         | 
| 63 | 
            +
            - lib/tasks/inplace_i18n_tasks.rake
         | 
| 64 | 
            +
            homepage: http://ignite.digitalignition.net/
         | 
| 65 | 
            +
            licenses: []
         | 
| 66 | 
            +
             | 
| 67 | 
            +
            post_install_message: 
         | 
| 68 | 
            +
            rdoc_options: []
         | 
| 69 | 
            +
             | 
| 70 | 
            +
            require_paths: 
         | 
| 71 | 
            +
            - lib
         | 
| 72 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         | 
| 73 | 
            +
              none: false
         | 
| 74 | 
            +
              requirements: 
         | 
| 75 | 
            +
              - - ">="
         | 
| 76 | 
            +
                - !ruby/object:Gem::Version 
         | 
| 77 | 
            +
                  hash: 3
         | 
| 78 | 
            +
                  segments: 
         | 
| 79 | 
            +
                  - 0
         | 
| 80 | 
            +
                  version: "0"
         | 
| 81 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         | 
| 82 | 
            +
              none: false
         | 
| 83 | 
            +
              requirements: 
         | 
| 84 | 
            +
              - - ">="
         | 
| 85 | 
            +
                - !ruby/object:Gem::Version 
         | 
| 86 | 
            +
                  hash: 3
         | 
| 87 | 
            +
                  segments: 
         | 
| 88 | 
            +
                  - 0
         | 
| 89 | 
            +
                  version: "0"
         | 
| 90 | 
            +
            requirements: []
         | 
| 91 | 
            +
             | 
| 92 | 
            +
            rubyforge_project: inplace_i18n
         | 
| 93 | 
            +
            rubygems_version: 1.8.10
         | 
| 94 | 
            +
            signing_key: 
         | 
| 95 | 
            +
            specification_version: 3
         | 
| 96 | 
            +
            summary: Inplace editing for rails i18n.
         | 
| 97 | 
            +
            test_files: []
         | 
| 98 | 
            +
             |