diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 3d5f6813b..143bc3398 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -475,10 +475,6 @@ Rails/I18nLocaleAssignment: Exclude: - 'spec/features/locale_spec.rb' -# Offense count: 40 -Rails/I18nLocaleTexts: - Enabled: false - # Offense count: 1 # Configuration parameters: IgnoreScopes. Rails/InverseOf: diff --git a/app/controllers/admin/crop_companions_controller.rb b/app/controllers/admin/crop_companions_controller.rb index 1ca9122a8..b21841b11 100644 --- a/app/controllers/admin/crop_companions_controller.rb +++ b/app/controllers/admin/crop_companions_controller.rb @@ -15,7 +15,7 @@ module Admin def create @crop_companion = @crop.crop_companions.new(crop_companion_params) if @crop_companion.save - redirect_to admin_crop_crop_companions_path(@crop), notice: 'Companion was successfully created.' + redirect_to admin_crop_crop_companions_path(@crop), notice: t('crop_companions.created') else render :new end @@ -24,7 +24,7 @@ module Admin def destroy @crop_companion = @crop.crop_companions.find(params[:id]) @crop_companion.destroy - redirect_to admin_crop_crop_companions_path(@crop), notice: 'Companion was successfully destroyed.' + redirect_to admin_crop_crop_companions_path(@crop), notice: t('crop_companions.deleted') end private diff --git a/app/controllers/admin/versions_controller.rb b/app/controllers/admin/versions_controller.rb index ff2691642..bd37a95e5 100644 --- a/app/controllers/admin/versions_controller.rb +++ b/app/controllers/admin/versions_controller.rb @@ -9,9 +9,9 @@ module Admin @version = PaperTrail::Version.find(params[:id]) @object = @version.reify if @object.save - redirect_to admin_crops_path, notice: "Reverted to version from #{@version.created_at.strftime('%B %d, %Y')}" + redirect_to admin_crops_path, notice: t('messages.revert_success', date: @version.created_at.strftime('%B %d, %Y')) else - redirect_to admin_crops_path, alert: "Could not revert to version from #{@version.created_at.strftime('%B %d, %Y')}. Errors: #{@object.errors.full_messages.to_sentence}" + redirect_to admin_crops_path, alert: t('messages.revert_error', date: @version.created_at.strftime('%B %d, %Y'), errors: @object.errors.full_messages.to_sentence) end end diff --git a/app/controllers/alternate_names_controller.rb b/app/controllers/alternate_names_controller.rb index d95b1667c..4c975cab8 100644 --- a/app/controllers/alternate_names_controller.rb +++ b/app/controllers/alternate_names_controller.rb @@ -30,7 +30,7 @@ class AlternateNamesController < ApplicationController @alternate_name = AlternateName.new(alternate_name_params) if @alternate_name.save - redirect_to @alternate_name.crop, notice: 'Alternate name was successfully created.' + redirect_to @alternate_name.crop, notice: t('alternate_names.created') else render action: "new" end @@ -40,7 +40,7 @@ class AlternateNamesController < ApplicationController # PUT /alternate_names/1.json def update if @alternate_name.update(alternate_name_params) - redirect_to @alternate_name.crop, notice: 'Alternate name was successfully updated.' + redirect_to @alternate_name.crop, notice: t('alternate_names.updated') else render action: "edit" end @@ -51,7 +51,7 @@ class AlternateNamesController < ApplicationController def destroy @crop = @alternate_name.crop @alternate_name.destroy - redirect_to @crop, notice: 'Alternate name was successfully deleted.' + redirect_to @crop, notice: t('alternate_names.deleted') end private diff --git a/app/controllers/authentications_controller.rb b/app/controllers/authentications_controller.rb index f3588cbdf..e8c03abbd 100644 --- a/app/controllers/authentications_controller.rb +++ b/app/controllers/authentications_controller.rb @@ -24,9 +24,9 @@ class AuthenticationsController < ApplicationController name: ) - flash[:notice] = "Authentication successful." + flash[:notice] = t('messages.auth_success') else - flash[:notice] = "Authentication failed." + flash[:notice] = t('messages.auth_failed') end redirect_to request.env['omniauth.origin'] || edit_member_registration_path end diff --git a/app/controllers/follows_controller.rb b/app/controllers/follows_controller.rb index 35bc3199f..94eff7680 100644 --- a/app/controllers/follows_controller.rb +++ b/app/controllers/follows_controller.rb @@ -13,9 +13,9 @@ class FollowsController < ApplicationController @follow = current_member.follows.build(followed: Member.find(params[:followed])) if @follow.save - flash[:notice] = "Followed #{@follow.followed.login_name}" + flash[:notice] = t('messages.followed', name: @follow.followed.login_name) else - flash[:error] = "Already following or error while following." + flash[:error] = t('messages.follow_error') end redirect_back_or_to(root_path) end @@ -25,7 +25,7 @@ class FollowsController < ApplicationController @unfollowed = @follow.followed @follow.destroy - flash[:notice] = "Unfollowed #{@unfollowed.login_name}" + flash[:notice] = t('messages.unfollowed', name: @unfollowed.login_name) redirect_to @unfollowed end diff --git a/app/controllers/forums_controller.rb b/app/controllers/forums_controller.rb index bc75da5fa..179c96c69 100644 --- a/app/controllers/forums_controller.rb +++ b/app/controllers/forums_controller.rb @@ -32,14 +32,14 @@ class ForumsController < ApplicationController # POST /forums.json def create @forum = Forum.new(forum_params) - flash[:notice] = 'Forum was successfully created.' if @forum.save + flash[:notice] = t('forums.created') if @forum.save respond_with(@forum) end # PUT /forums/1 # PUT /forums/1.json def update - flash[:notice] = 'Forum was successfully updated.' if @forum.update(forum_params) + flash[:notice] = t('forums.updated') if @forum.update(forum_params) respond_with(@forum) end @@ -47,7 +47,7 @@ class ForumsController < ApplicationController # DELETE /forums/1.json def destroy @forum.destroy - flash[:notice] = 'Forum was successfully deleted' + flash[:notice] = t('forums.deleted') redirect_to forums_url end diff --git a/app/controllers/likes_controller.rb b/app/controllers/likes_controller.rb index 3093ce42e..b205ec220 100644 --- a/app/controllers/likes_controller.rb +++ b/app/controllers/likes_controller.rb @@ -14,7 +14,7 @@ class LikesController < ApplicationController @like.likeable.reindex(refresh: true) success(@like, liked_by_member: true, status_code: :created) else - failed(@like, message: 'Unable to like') + failed(@like, message: t('messages.unable_to_like')) end end @@ -29,7 +29,7 @@ class LikesController < ApplicationController @like.likeable.reindex(refresh: true) success(@like, liked_by_member: false, status_code: :ok) else - failed(@like, message: 'Unable to unlike') + failed(@like, message: t('messages.unable_to_unlike')) end end diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index 0d55de038..f4394d8a3 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -10,7 +10,7 @@ require './lib/actions/oauth_signup_action' # class OmniauthCallbacksController < Devise::OmniauthCallbacksController def failure - flash[:alert] = "Authentication failed." + flash[:alert] = t('messages.auth_failed') redirect_to request.env['omniauth.origin'] || "/" end diff --git a/app/controllers/places_controller.rb b/app/controllers/places_controller.rb index a30c1ae98..cfec33fa4 100644 --- a/app/controllers/places_controller.rb +++ b/app/controllers/places_controller.rb @@ -33,7 +33,7 @@ class PlacesController < ApplicationController def search if params[:new_place].empty? - redirect_to places_path, alert: 'Please enter a valid location' + redirect_to places_path, alert: t('messages.invalid_location') else redirect_to place_path(params[:new_place]) end diff --git a/app/controllers/plantings_controller.rb b/app/controllers/plantings_controller.rb index a696e9c03..bc443fe8e 100644 --- a/app/controllers/plantings_controller.rb +++ b/app/controllers/plantings_controller.rb @@ -116,11 +116,11 @@ class PlantingsController < DataController new_planting.finished_at = nil if new_planting.save - redirect_to edit_planting_path(new_planting), notice: 'Planting was successfully transplanted.' + redirect_to edit_planting_path(new_planting), notice: t('messages.transplant_success') else # if the save fails, we should probably roll back the finishing of the original planting @planting.update(finished: false, finished_at: nil) - redirect_to @planting, alert: "There was an error transplanting the planting: #{new_planting.errors.full_messages.to_sentence}" + redirect_to @planting, alert: t('messages.transplant_error', errors: new_planting.errors.full_messages.to_sentence) end end diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index b1affe635..01239a601 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -29,17 +29,17 @@ class PostsController < ApplicationController def create params[:post][:author_id] = current_member.id @post = Post.new(post_params) - flash[:notice] = 'Post was successfully created.' if @post.save + flash[:notice] = t('posts.created') if @post.save respond_with(@post) end def update - flash[:notice] = 'Post was successfully updated.' if @post.update(post_params) + flash[:notice] = t('posts.updated') if @post.update(post_params) respond_with(@post) end def destroy - flash[:notice] = 'Post was deleted.' if @post.destroy + flash[:notice] = t('posts.deleted') if @post.destroy respond_with(@post) end diff --git a/app/controllers/scientific_names_controller.rb b/app/controllers/scientific_names_controller.rb index d815de94a..525563235 100644 --- a/app/controllers/scientific_names_controller.rb +++ b/app/controllers/scientific_names_controller.rb @@ -54,7 +54,7 @@ class ScientificNamesController < ApplicationController def destroy @crop = @scientific_name.crop @scientific_name.destroy - flash[:notice] = 'Scientific name was successfully deleted.' + flash[:notice] = t('scientific_names.deleted') respond_with(@crop) end diff --git a/app/controllers/seeds_controller.rb b/app/controllers/seeds_controller.rb index 6dd2741cd..46e00c0cc 100644 --- a/app/controllers/seeds_controller.rb +++ b/app/controllers/seeds_controller.rb @@ -61,7 +61,7 @@ class SeedsController < DataController @seed.finished ||= false @seed.owner = current_member @seed.crop = @seed.parent_planting.crop if @seed.parent_planting - flash[:notice] = "Successfully added #{@seed.crop} seed to your stash." if @seed.save + flash[:notice] = t('seeds.added_to_stash', crop: @seed.crop) if @seed.save if params[:return] == 'planting' respond_with(@seed, location: @seed.parent_planting) else @@ -70,7 +70,7 @@ class SeedsController < DataController end def update - flash[:notice] = 'Seed was successfully updated.' if @seed.update(seed_params) + flash[:notice] = t('seeds.updated') if @seed.update(seed_params) respond_with(@seed) end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 47063d75d..fb5d0f226 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -5,7 +5,7 @@ class SessionsController < Devise::SessionsController def create super do |_resource| - flash[:alert] = "There are crops waiting to be wrangled." if Crop.pending_approval.present? && current_member.role?(:crop_wrangler) + flash[:alert] = t('messages.crops_waiting') if Crop.pending_approval.present? && current_member.role?(:crop_wrangler) end end end diff --git a/app/models/crop.rb b/app/models/crop.rb index b04eb3325..351ed0ae7 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -57,13 +57,13 @@ class Crop < ApplicationRecord validates :en_wikipedia_url, format: { with: %r{\Ahttps?://en\.wikipedia\.org/wiki/[[:alnum:]%_.()-]+\z}, - message: 'is not a valid English Wikipedia URL' + message: :not_a_valid_wikipedia_url }, if: :approved? validates :en_youtube_url, format: { with: %r{\A(?:https?://)?(?:www\.)?(?:youtube(?:-nocookie)?\.com/(?:(?:v|e(?:mbed)?)/|\S*?[?&]v=)|youtu\.be/)[a-zA-Z0-9_-]{11}(?:[?&]\S*)?\z}, - message: 'is not a valid YouTube URL' + message: :not_a_valid_youtube_url }, allow_blank: true validates :name, uniqueness: { scope: :approval_status }, if: :pending? @@ -190,12 +190,12 @@ class Crop < ApplicationRecord return if rejected? return unless reason_for_rejection.present? || rejection_notes.present? - errors.add(:approval_status, "must be rejected if a reason for rejection is present") + errors.add(:approval_status, :rejection_reason_required) end def must_have_meaningful_reason_for_rejection return unless reason_for_rejection == "other" && rejection_notes.blank? - errors.add(:rejection_notes, "must be added if the reason for rejection is \"other\"") + errors.add(:rejection_notes, :rejection_notes_required) end end diff --git a/app/models/garden.rb b/app/models/garden.rb index 5d3f04adb..ac55b5ffa 100644 --- a/app/models/garden.rb +++ b/app/models/garden.rb @@ -32,7 +32,7 @@ class Garden < ApplicationRecord validates :name, uniqueness: { scope: :owner_id } validates :name, - format: { without: /\n/, message: "must contain no newlines" }, + format: { without: /\n/, message: :no_newlines }, allow_blank: false, presence: true, length: { maximum: 255 } @@ -53,7 +53,7 @@ class Garden < ApplicationRecord "acres" => "acre" }.freeze validates :area_unit, inclusion: { in: AREA_UNITS_VALUES.values, - message: "%s is not a valid area unit" }, + message: :not_a_valid_area_unit }, allow_blank: true def cleanup_area diff --git a/app/models/garden_collaborator.rb b/app/models/garden_collaborator.rb index 520303437..7604ad286 100644 --- a/app/models/garden_collaborator.rb +++ b/app/models/garden_collaborator.rb @@ -11,7 +11,7 @@ class GardenCollaborator < ApplicationRecord return unless member return unless garden - errors.add(:member_id, "cannot be the garden owner") if garden.owner == member + errors.add(:member_id, :cannot_be_garden_owner) if garden.owner == member end def member_slug diff --git a/app/models/harvest.rb b/app/models/harvest.rb index 7fba64bc8..92ed0f6eb 100644 --- a/app/models/harvest.rb +++ b/app/models/harvest.rb @@ -58,18 +58,18 @@ class Harvest < ApplicationRecord ## ## Validations validates :crop, approved: true - validates :crop, presence: { message: "must be present and exist in our database" } - validates :plant_part, presence: { message: "must be present and exist in our database" } + validates :crop, presence: { message: :crop_not_found } + validates :plant_part, presence: { message: :crop_not_found } validates :harvested_at, presence: true validates :quantity, allow_nil: true, numericality: { only_integer: false, greater_than_or_equal_to: 0 } validates :unit, allow_blank: true, inclusion: { - in: UNITS_VALUES.values, message: "%s is not a valid unit" + in: UNITS_VALUES.values, message: :not_a_valid_unit } validates :weight_quantity, allow_nil: true, numericality: { only_integer: false } validates :weight_unit, allow_blank: true, inclusion: { - in: WEIGHT_UNITS_VALUES.values, message: "%s is not a valid unit" + in: WEIGHT_UNITS_VALUES.values, message: :not_a_valid_unit } validate :crop_must_match_planting validate :owner_must_match_planting @@ -147,7 +147,7 @@ class Harvest < ApplicationRecord def crop_must_match_planting return if planting.blank? # only check if we are linked to a planting - errors.add(:planting, "must be the same crop") unless crop == planting.crop + errors.add(:planting, :same_crop_required) unless crop == planting.crop end def owner_must_match_planting @@ -155,14 +155,13 @@ class Harvest < ApplicationRecord return if owner == planting.owner || planting.garden.garden_collaborators.where(member_id: owner).any? - errors.add(:owner, - "of harvest must be the same as planting, or a collaborator on that garden") + errors.add(:owner, :same_owner_required) end def harvest_must_be_after_planting # only check if we are linked to a planting return unless harvested_at.present? && planting.present? && planting.planted_at.present? - errors.add(:planting, "cannot be harvested before planting") unless harvested_at > planting.planted_at + errors.add(:planting, :harvest_after_planted) unless harvested_at > planting.planted_at end end diff --git a/app/models/member.rb b/app/models/member.rb index 3bfcf9d7c..a6503c940 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -96,21 +96,21 @@ class Member < ApplicationRecord validates :tos_agreement, acceptance: { allow_nil: true, accept: true } validates :login_name, length: { - minimum: 2, maximum: 25, message: "should be between 2 and 25 characters long" + minimum: 2, maximum: 25, message: :login_name_length }, exclusion: { - in: %w(growstuff admin moderator staff nearby), message: "name is reserved" + in: %w(growstuff admin moderator staff nearby), message: :login_name_reserved }, format: { - with: /\A\w+\z/, message: "may only include letters, numbers, or underscores" + with: /\A\w+\z/, message: :login_name_format }, uniqueness: { case_sensitive: false } - validates :website_url, format: { with: %r{\Ahttps?://}, message: "must start with http:// or https://" }, allow_blank: true - validates :other_url, format: { with: %r{\Ahttps?://}, message: "must start with http:// or https://" }, allow_blank: true + validates :website_url, format: { with: %r{\Ahttps?://}, message: :url_format }, allow_blank: true + validates :other_url, format: { with: %r{\Ahttps?://}, message: :url_format }, allow_blank: true validates :instagram_handle, :facebook_handle, :bluesky_handle, - format: { without: %r{\Ahttps?://|/}, message: "should be a handle, not a URL" }, allow_blank: true + format: { without: %r{\Ahttps?://|/}, message: :handle_format }, allow_blank: true # # Triggers diff --git a/app/models/photo_association.rb b/app/models/photo_association.rb index 6e9ad47e7..7197cfb71 100644 --- a/app/models/photo_association.rb +++ b/app/models/photo_association.rb @@ -29,12 +29,12 @@ class PhotoAssociation < ApplicationRecord def photo_and_item_have_same_owner return if photographable_type == 'Crop' - errors.add(:photo, "must have same owner as item it links to") unless photographable.owner_id == photo.owner_id + errors.add(:photo, :photo_owner_mismatch) unless photographable.owner_id == photo.owner_id end def crop_present return unless %w(Planting Seed Harvest).include?(photographable_type) - errors.add(:crop_id, "failed to calculate crop") if crop_id.blank? + errors.add(:crop_id, :calculate_crop_failed) if crop_id.blank? end end diff --git a/app/models/planting.rb b/app/models/planting.rb index 7cc82c731..05ecc99ec 100644 --- a/app/models/planting.rb +++ b/app/models/planting.rb @@ -72,7 +72,7 @@ class Planting < ApplicationRecord ## ## Validations validates :garden, presence: true - validates :crop, presence: true, approved: { message: "must be present and exist in our database" } + validates :crop, presence: true, approved: { message: :crop_must_be_approved } validate :finished_must_be_after_planted validate :owner_must_match_garden_owner validate :cannot_be_finished_and_failed @@ -80,10 +80,10 @@ class Planting < ApplicationRecord only_integer: true, greater_than_or_equal_to: 0 } validates :sunniness, allow_blank: true, inclusion: { - in: SUNNINESS_VALUES, message: "%s is not a valid sunniness value" + in: SUNNINESS_VALUES, message: :not_a_valid_sunniness } validates :planted_from, allow_blank: true, inclusion: { - in: PLANTED_FROM_VALUES, message: "%s is not a valid planting method" + in: PLANTED_FROM_VALUES, message: :not_a_valid_planting_method } validates :overall_rating, allow_blank: true, numericality: { only_integer: true, greater_than_or_equal_to: 1, less_than_or_equal_to: 5 @@ -132,20 +132,19 @@ class Planting < ApplicationRecord private def cannot_be_finished_and_failed - errors.add(:failed, "can't be true if planting is also finished") if finished && failed + errors.add(:failed, :failed_and_finished) if finished && failed end # check that any finished_at date occurs after planted_at def finished_must_be_after_planted return unless planted_at && finished_at # only check if we have both - errors.add(:finished_at, "must be after the planting date") unless planted_at < finished_at + errors.add(:finished_at, :finished_after_planted) unless planted_at < finished_at end def owner_must_match_garden_owner return if owner == garden.owner || garden.garden_collaborators.where(member_id: owner).any? - errors.add(:owner, - "must be the same as garden, or a collaborator on that garden") + errors.add(:owner, :same_owner_required) end end diff --git a/app/models/seed.rb b/app/models/seed.rb index 090c8f022..d3d8fb47d 100644 --- a/app/models/seed.rb +++ b/app/models/seed.rb @@ -28,7 +28,7 @@ class Seed < ApplicationRecord # # Validations validates :crop, approved: true - validates :crop, presence: { message: "must be present and exist in our database" } + validates :crop, presence: { message: :crop_not_found } validates :quantity, allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 } validates :days_until_maturity_min, allow_nil: true, @@ -36,20 +36,15 @@ class Seed < ApplicationRecord validates :days_until_maturity_max, allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 } validates :tradable_to, allow_blank: false, - inclusion: { in: TRADABLE_TO_VALUES, message: "You may only trade seed nowhere, " \ - "locally, nationally, or internationally" } + inclusion: { in: TRADABLE_TO_VALUES, message: :tradable_to_inclusion } validates :organic, allow_blank: false, - inclusion: { in: ORGANIC_VALUES, message: "You must say whether the seeds " \ - "are organic or not, or that you don't know" } + inclusion: { in: ORGANIC_VALUES, message: :organic_inclusion } validates :gmo, allow_blank: false, - inclusion: { in: GMO_VALUES, message: "You must say whether the seeds are " \ - "genetically modified or not, or that you don't know" } + inclusion: { in: GMO_VALUES, message: :gmo_inclusion } validates :heirloom, allow_blank: false, - inclusion: { in: HEIRLOOM_VALUES, message: "You must say whether the seeds" \ - "are heirloom, hybrid, or unknown" } + inclusion: { in: HEIRLOOM_VALUES, message: :heirloom_inclusion } validates :source, allow_blank: true, - inclusion: { in: SOURCE_VALUES, message: "You must say where the seeds are from," \ - "or that you don't know" } + inclusion: { in: SOURCE_VALUES, message: :source_inclusion } # # Delegations diff --git a/config/locales/en.yml b/config/locales/en.yml index d0a141d10..8885271fc 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -63,6 +63,56 @@ en: seed: one: seed other: seeds + errors: + messages: + crop_not_found: must be present and exist in our database + crop_must_be_approved: must be present and exist in our database + failed_and_finished: "can't be true if planting is also finished" + finished_after_planted: must be after the planting date + rejection_reason_required: must be rejected if a reason for rejection is present + rejection_notes_required: "must be added if the reason for rejection is \"other\"" + same_crop_required: must be the same crop + harvest_after_planted: cannot be harvested before planting + cannot_be_garden_owner: cannot be the garden owner + same_owner_required: "of harvest must be the same as planting, or a collaborator on that garden" + photo_owner_mismatch: must have same owner as item it links to + calculate_crop_failed: failed to calculate crop + not_a_valid_wikipedia_url: is not a valid English Wikipedia URL + not_a_valid_youtube_url: is not a valid YouTube URL + not_a_valid_sunniness: "%{value} is not a valid sunniness value" + not_a_valid_planting_method: "%{value} is not a valid planting method" + not_a_valid_unit: "%{value} is not a valid unit" + not_a_valid_area_unit: "%{value} is not a valid area unit" + no_newlines: must contain no newlines + models: + member: + attributes: + login_name: + login_name_length: should be between 2 and 25 characters long + login_name_reserved: name is reserved + login_name_format: may only include letters, numbers, or underscores + website_url: + url_format: "must start with http:// or https://" + other_url: + url_format: "must start with http:// or https://" + instagram_handle: + handle_format: should be a handle, not a URL + facebook_handle: + handle_format: should be a handle, not a URL + bluesky_handle: + handle_format: should be a handle, not a URL + seed: + attributes: + tradable_to: + tradable_to_inclusion: "You may only trade seed nowhere, locally, nationally, or internationally" + organic: + organic_inclusion: "You must say whether the seeds are organic or not, or that you don't know" + gmo: + gmo_inclusion: "You must say whether the seeds are genetically modified or not, or that you don't know" + heirloom: + heirloom_inclusion: "You must say whether the seeds are heirloom, hybrid, or unknown" + source: + source_inclusion: "You must say where the seeds are from, or that you don't know" application_helper: title: title: @@ -112,6 +162,9 @@ en: forums: index: title: Forums + created: Forum was successfully created. + updated: Forum was successfully updated. + deleted: Forum was successfully deleted. gardens: created: Garden was successfully created. deleted: Garden was successfully deleted. @@ -208,6 +261,8 @@ en: trade_to: Will trade to unspecified: unspecified view_all: View all seeds + added_to_stash: Successfully added %{crop} seed to your stash. + updated: Seed was successfully updated. stats: member_linktext: "%{count} members" message_html: So far, %{member} have planted %{number_crops} %{number_plantings} in %{number_gardens}; and %{contributors} people have contributed to our code on %{github}! @@ -275,6 +330,21 @@ en: links: my_gardens: My gardens + messages: + auth_success: Authentication successful. + auth_failed: Authentication failed. + crops_waiting: There are crops waiting to be wrangled. + followed: "Followed %{name}" + unfollowed: "Unfollowed %{name}" + follow_error: Already following or error while following. + transplant_success: Planting was successfully transplanted. + transplant_error: "There was an error transplanting the planting: %{errors}" + revert_success: "Reverted to version from %{date}" + revert_error: "Could not revert to version from %{date}. Errors: %{errors}" + invalid_location: Please enter a valid location + unable_to_like: Unable to like + unable_to_unlike: Unable to unlike + members: edit_profile: Edit profile index: @@ -342,10 +412,22 @@ en: progress_0_not_planted_yet: 'Progress: 0% - not planted yet' posts: write_blog_post: Write blog post + created: Post was successfully created. + updated: Post was successfully updated. + deleted: Post was deleted. index: title: author_posts: "%{author} posts" default: Everyone's posts + scientific_names: + deleted: Scientific name was successfully deleted. + alternate_names: + created: Alternate name was successfully created. + updated: Alternate name was successfully updated. + deleted: Alternate name was successfully deleted. + crop_companions: + created: Companion was successfully created. + deleted: Companion was successfully destroyed. seeds: form: trade_help: > @@ -361,6 +443,7 @@ en: owner_seeds: "%{owner} seeds" save_seeds: Save seeds string: "%{crop} seeds belonging to %{owner}" + added_to_stash: Successfully added %{crop} seed to your stash. unauthorized: create: all: Please sign in or sign up to create a %{subject}.