class Fame::XliffExport

Handles import and export of .xliff files

Public Class Methods

new(xcode_proj_path) click to toggle source

Initializer @param xcode_proj_path A path to a .xcodeproj file whose contents should be localized.

# File lib/fame/xliff_export.rb, line 14
def initialize(xcode_proj_path)
  @xcode_proj = XcodeProject.new(xcode_proj_path)
end

Public Instance Methods

export(path, ib_nodes) click to toggle source

Exports all .xliff files for the current Xcode project @param path A path to a folder where exported .xliff files should be placed. @param ib_nodes An array of ‘LocalizedNode`s, generated from `InterfaceBuilder.nodes`.

# File lib/fame/xliff_export.rb, line 23
def export(path, ib_nodes)
  # export localizations
  export_xliffs(path)

  # update translation units based on the settings provided in Interface Builder
  # Localizations are only exported if explicitly enabled via the fame Interface Builder integration (see Fame.swift file).
  update_xliff_translation_units(path, ib_nodes)
end

Private Instance Methods

export_xliffs(path) click to toggle source

Exports all .xliff files for the current Xcode project to the given path. @param path A path to a folder where exported .xliff files should be placed.

# File lib/fame/xliff_export.rb, line 38
def export_xliffs(path)
  # get all languages that should be exported to separate .xliff files
  languages = @xcode_proj.all_languages
    .map { |l| "-exportLanguage #{l}" }
    .join(" ")

  `xcodebuild -exportLocalizations -localizationPath #{path} -project #{@xcode_proj.xcode_proj_path} #{languages}`
end
read_xliff_file(path) click to toggle source

Reads the document at the given path and parses it into a ‘Nokogiri` XML doc. @param path The path the xliff file that should be parsed @return [Nokogiri::XML] A `Nokogiri` XML document representing the xliff

# File lib/fame/xliff_export.rb, line 106
def read_xliff_file(path)
  xliff = File.open(path)
  doc = Nokogiri::XML(xliff)
  xliff.close

  doc
end
update_xliff_translation_units(path, ib_nodes) click to toggle source

Modifies all .xliff files based on the settings extracted from Interface Builder nodes.

# File lib/fame/xliff_export.rb, line 50
def update_xliff_translation_units(path, ib_nodes)
  @xcode_proj.all_languages.each do |language|
    xliff_path = File.join(path, "#{language}.xliff")
    puts "Updating translation units for #{language}".blue

    # Read XLIFF file
    raise "File #{xliff_path} does not exist" unless File.exists? xliff_path
    doc = read_xliff_file(xliff_path)

    # Extract all translation units from the xliff
    trans_units = doc.xpath('//xmlns:trans-unit')

    # Loop over the Interface Builder nodes and update the xliff file based on their settings
    ib_nodes.each do |ib_node|
      # Select nodes connected to original_id
      units = trans_units.select do |u|
        u_id = u["id"] rescue ""
        u_id.start_with?(ib_node.original_id)
      end

      # Update or remove nodes
      units.each do |unit|
        if ib_node.i18n_enabled
          # Update comment
          comment = unit.xpath("xmlns:note")
          comment.children.first.content = ib_node.formatted_info
        else
          # Remove translation unit, since it should not be translated
          unit.remove
        end
      end

      # Print status
      if units.count > 0
        status = ib_node.i18n_enabled ? "updated".green : "removed".red
        puts [
          "  ✔︎".green,
          "#{units.count} translation unit(s)".black,
          status,
          "for".light_black,
          "#{ib_node.original_id}".black,
          "#{ib_node.formatted_info}".light_black
        ].join(" ")
      end
    end

    # Write updated XLIFF file to disk
    write_xliff_file(doc, xliff_path)
  end
end
write_xliff_file(doc, path) click to toggle source

Writes the given ‘Nokogiri` doc to the given path @param doc A Nokogiri XML document @param path The path the `doc` should be written to

# File lib/fame/xliff_export.rb, line 119
def write_xliff_file(doc, path)
  file = File.open(path, "w")
  doc.write_xml_to(file)
  file.close
end