motion-phrase 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,9 +1,19 @@
1
- # Motion::Phrase
1
+ # motion-phrase
2
2
 
3
- TODO: Write a gem description
3
+ motion-phrase lets you connect your RubyMotion application to PhraseApp and enables you to benefit from the best internationalization workflow for your (iOS) projects.
4
+
5
+ It lets you use iOS Localizable.strings files to store and read translations but at the same time work on your translation files collaboratively with translators, developers and product managers.
6
+
7
+ [Learn more about PhraseApp](https://phraseapp.com/)
4
8
 
5
9
  ## Installation
6
10
 
11
+ Using the service requires a PhraseApp account. Just sign up at [phraseapp.com/signup](https://phraseapp.com/signup) and get your free trial account (we offer free plans for small and open source projects).
12
+
13
+ You can skip the introduction wizard and simply create your first project to get your Auth Token directly from the project overview in PhraseApp.
14
+
15
+ ### Install the Gem
16
+
7
17
  Add this line to your application's Gemfile:
8
18
 
9
19
  gem 'motion-phrase'
@@ -15,10 +25,106 @@ And then execute:
15
25
  Or install it yourself as:
16
26
 
17
27
  $ gem install motion-phrase
28
+
29
+ Require the gem (unless you use bundler):
30
+
31
+ require 'motion-phrase'
32
+
33
+ ### Configure PhraseApp
34
+
35
+ Add the Auth Token to your application's Rakefile:
36
+
37
+ Motion::Project::App.setup do |app|
38
+ app.name = "Test Application"
39
+ . . .
40
+ app.phrase.auth_token = "YOUR_AUTH_TOKEN"
41
+ . . .
42
+ end
43
+
44
+ This will automatically create the `phrase_config.rb` configuration file in your app folder during the first build process.
45
+
46
+ Now you can initialize your PhraseApp setup using rake:
47
+
48
+ rake phrase:init AUTH_TOKEN=YOUR_AUTH_TOKEN
49
+
50
+ This will:
51
+
52
+ 1. Create the first locale in your PhraseApp project (and make it your default locale as well)
53
+ 2. Create a `.phrase` config file that contains information required by the underlying [phrase gem](https://github.com/phrase/phrase)
18
54
 
19
55
  ## Usage
20
56
 
21
- TODO: Write usage instructions here
57
+ Using PhraseApp with motion-phrase enables you to:
58
+
59
+ 1. Send new translations to the PhraseApp API automatically without having to write them into your Localizable.strings file or uploading them - just by browsing the app.
60
+ 2. Upload and download your most recent translations from/to the PhraseApp API using rake commands.
61
+ 3. Spend less time sending emails or fixing broken Localizable.strings files ;-)
62
+
63
+ ### Localizing Strings ###
64
+
65
+ The first step towards a localized app is to localize all strings by extending them with their localized counterparts. This can be done by simply calling the `#__` method on each string that is implemented by motion-phrase:
66
+
67
+ "Hello World"
68
+
69
+ now becomes:
70
+
71
+ "Hello World".__
72
+
73
+ or (when using a fallback translation):
74
+
75
+ "Hello World".__("My fallback translation")
76
+
77
+ Of course you can use more generic names for your keys as well, such as:
78
+
79
+ "HOME_WELCOME_BUTTON_LABEL".__
80
+
81
+
82
+
83
+ [Learn more about localization in iOS](https://developer.apple.com/internationalization/)
84
+
85
+ ### Browsing translations in your app
86
+
87
+ Simply build and run your app (in the simulator). When in development mode, motion-phrase will send all of your localized strings to PhraseApp automatically! Log into your [PhraseApp account](https://phraseapp.com/account/login) and check your newly created translation keys. If you already have your localization files in the correct place, it will transmit translations as well.
88
+
89
+ ### Push localization files
90
+
91
+ If you already have localization files in place, you can transmit them to PhraseApp by using the following rake command:
92
+
93
+ rake phrase:push
94
+
95
+ Simply execute this from inside your project directory and it will upload all Localizable.strings files that are found in your `resources` folder. All new keys and translation will be created in your PhraseApp project during the upload.
96
+
97
+ ### Pull localization files
98
+
99
+ Of course you want to include all recent translations in your application before releasing or testing it. Simply fetch all translations from PhraseApp using rake:
100
+
101
+ rake phrase:pull
102
+
103
+ This will download and replace all existing Localizable.strings files that sit in your `resources` folder. You can now build/test/release your application with the most recent localization files.
104
+
105
+ ### Extended Usage ###
106
+
107
+ motion-phrase uses the [phrase gem](https://github.com/phrase/phrase) to communicate with the service. Feel free to use the `phrase` command to gain control over extended configuration options.
108
+
109
+ [Learn more about phrase gem](https://phraseapp.com/docs/installation/general-information)
110
+
111
+ ## Your new workflow (Best Practice)
112
+
113
+ Once you have your PhraseApp integration up and running, we recommend the following workflow:
114
+
115
+ 1. Let developers introduce new keys (localizable strings) in the code
116
+ 2. Browse the new feature in your app
117
+ 3. Log into PhraseApp and fill out the remaining translations in all other locale (or simply order the missing translations through our expert network)
118
+ 4. Download all translations using the pull command
119
+ 5. Ship it ;-)
120
+
121
+ ## Important ##
122
+
123
+ Please remember the following hints (especially when something goes wrong):
124
+
125
+ * The locale/language that you want to send translations from must exist in your PhraseApp project (e.g. if you are running your simulator in French and want to send translations to PhraseApp by browsing the app, you first have to create a "fr" locale in your PhraseApp project)
126
+ * We only transmit translations to the API when you run your app in development mode (`RUBYMOTION_ENV` must be development)
127
+ * **Please double-check that no API traffic is triggered in the release/releasable version of your application!!!**
22
128
 
23
129
  ## Contributing
24
130
 
@@ -27,3 +133,8 @@ TODO: Write usage instructions here
27
133
  3. Commit your changes (`git commit -am 'Add some feature'`)
28
134
  4. Push to the branch (`git push origin my-new-feature`)
29
135
  5. Create new Pull Request
136
+
137
+ ## Support
138
+
139
+ * [PhraseApp documentation](https://phraseapp.com/docs)
140
+ * [PhraseApp Support Channel](https://phraseapp.com/support)
@@ -1,25 +1,30 @@
1
1
  module MotionPhrase
2
2
  class ApiClient
3
+ API_CLIENT_IDENTIFIER = "motion_phrase"
4
+ API_BASE_URI = "https://phraseapp.com/api/v1/"
5
+
3
6
  def self.sharedClient
4
7
  Dispatch.once { @instance ||= new }
5
8
  @instance
6
9
  end
7
10
 
8
11
  def storeTranslation(keyName, content, fallbackContent, currentLocale)
9
- return false unless development?
12
+ return unless development?
10
13
 
14
+ content ||= fallbackContent
11
15
  data = {
12
- "locale" => currentLocale,
13
- "key" => keyName,
14
- "content" => content,
15
- "skip_verification" => true,
16
- "auth_token" => PHRASE_AUTH_TOKEN
16
+ locale: currentLocale,
17
+ key: keyName,
18
+ content: content,
19
+ allow_update: false,
20
+ skip_verification: true,
21
+ api_client: API_CLIENT_IDENTIFIER,
17
22
  }
18
- client.post("translations/store", data) do |result|
23
+ client.post("translations/store", authenticated(data)) do |result|
19
24
  if result.success?
20
- log "Stored Translation for #{keyName}"
25
+ log "Translation stored [#{data.inspect}]"
21
26
  elsif result.failure?
22
- log "Could not store translation for #{keyName}"
27
+ log "Error while storing translation [#{data.inspect}]"
23
28
  end
24
29
  end
25
30
  end
@@ -34,14 +39,18 @@ module MotionPhrase
34
39
  end
35
40
 
36
41
  def buildClient
37
- AFMotion::Client.build_shared(PHRASE_API_BASE_URI) do
42
+ AFMotion::Client.build_shared(API_BASE_URI) do
38
43
  header "Accept", "application/json"
39
44
  operation :json
40
45
  end
41
46
  end
42
47
 
43
48
  def log(msg="")
44
- $stdout.puts msg
49
+ $stdout.puts "PHRASEAPP #{msg}"
45
50
  end
51
+
52
+ def authenticated(params={})
53
+ params.merge(auth_token: PHRASE_AUTH_TOKEN)
54
+ end
46
55
  end
47
56
  end
@@ -1,3 +1,3 @@
1
1
  module MotionPhrase
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -5,6 +5,8 @@ end
5
5
  class PhraseConfig
6
6
  attr_accessor :auth_token
7
7
 
8
+ CONFIG_FILE = './app/phrase_config.rb'
9
+
8
10
  def initialize(config)
9
11
  @config = config
10
12
  end
@@ -18,17 +20,27 @@ private
18
20
  def create_phrase_config_file
19
21
  return unless @auth_token
20
22
 
21
- code = <<EOF
23
+ if config_file_exists? or config_file_content_outdated?
24
+ File.open(CONFIG_FILE, 'w') { |f| f.write(config_file_content) }
25
+ end
26
+ files = @config.files.flatten
27
+ files << CONFIG_FILE unless files.find { |f| File.expand_path(f) == File.expand_path(CONFIG_FILE) }
28
+ end
29
+
30
+ def config_file_exists?
31
+ File.exist?(CONFIG_FILE)
32
+ end
33
+
34
+ def config_file_content_outdated?
35
+ File.read(CONFIG_FILE) != config_file_content
36
+ end
37
+
38
+ def config_file_content
39
+ content = <<EOF
22
40
  # This file is automatically generated. Do not edit.
23
41
  PHRASE_AUTH_TOKEN = "#{@auth_token}"
24
- PHRASE_API_BASE_URI = "http://localhost:3000/api/v1/"
25
42
  EOF
26
- config_file = './app/phrase_config.rb'
27
- unless File.exist?(config_file)
28
- File.open(config_file, 'w') { |f| f.write(code) }
29
- end
30
- files = @config.files.flatten
31
- files << config_file unless files.find { |f| File.expand_path(f) == File.expand_path(config_file) }
43
+ content
32
44
  end
33
45
  end
34
46
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: motion-phrase
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-04 00:00:00.000000000 Z
12
+ date: 2013-06-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: phrase