Class: Imagekitio::Helper
- Inherits:
-
Object
- Object
- Imagekitio::Helper
- Defined in:
- lib/imagekitio/helpers/helper.rb
Instance Method Summary collapse
-
#build_transformation_string(transformations) ⇒ String
Generates transformation string from transformation objects.
-
#build_url(options) ⇒ String
Builds a URL with transformations applied.
-
#get_authentication_parameters(token: nil, expire: nil) ⇒ Hash{Symbol => String, Integer}
Generates authentication parameters for client-side file uploads using ImageKit’s Upload API V1.
-
#get_responsive_image_attributes(options) ⇒ Imagekitio::Models::ResponsiveImageAttributes
Generates responsive image attributes for use in HTML <img> tags.
-
#initialize(client:) ⇒ Helper
constructor
private
A new instance of Helper.
Constructor Details
#initialize(client:) ⇒ Helper
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of Helper.
336 337 338 |
# File 'lib/imagekitio/helpers/helper.rb', line 336 def initialize(client:) @client = client end |
Instance Method Details
#build_transformation_string(transformations) ⇒ String
Generates transformation string from transformation objects
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/imagekitio/helpers/helper.rb', line 134 def build_transformation_string(transformations) return "" unless transformations.is_a?(Array) parsed_transforms = [] # rubocop:disable Metrics/BlockLength transformations.each do |transform| next unless transform # Convert model to hash - all transformation inputs are expected to be BaseModel objects current_transform = transform.to_h parsed_transform_step = [] # rubocop:disable Metrics/BlockLength current_transform.each do |key, value| next if value.nil? || value.to_s.empty? # Handle overlay separately if key.to_s == "overlay" && value # Pass model object directly to process_overlay raw_string = (value) if raw_string && !raw_string.strip.empty? parsed_transform_step << raw_string end next end transform_key = Imagekitio::TransformationUtils.get_transform_key(key) transform_key = key.to_s if transform_key.empty? next if transform_key.empty? # Handle special boolean effects boolean_effects = %w[e-grayscale e-contrast e-removedotbg e-bgremove e-upscale e-retouch e-genvar] if boolean_effects.include?(transform_key) if value == true || value == "-" || value == "true" parsed_transform_step << transform_key end next end # Handle effects that can be boolean or have values value_effects = %w[e-sharpen e-shadow e-gradient e-usm e-dropshadow] if value_effects.include?(transform_key) && (value.to_s.strip.empty? || value == true || value == "true") parsed_transform_step << transform_key next end # Handle raw parameter if key.to_s == "raw" parsed_transform_step << value.to_s next end # Handle special cases for di and ff (need special encoding) if %w[di ff].include?(transform_key) processed_value = remove_leading_slash(remove_trailing_slash(value.to_s)) processed_value = processed_value.gsub("/", "@@") value = processed_value end # Handle streaming resolutions array if transform_key == "sr" && value.is_a?(Array) value = value.join("_") end # Special case for trim with empty string if transform_key == "t" && value.to_s.strip.empty? value = "true" end # Convert numeric values to integers if they're whole numbers if value.is_a?(Numeric) value = value.to_i if value == value.to_i end parsed_transform_step << "#{transform_key}#{Imagekitio::TransformationUtils.get_transform_key_value_delimiter}#{value}" end # rubocop:enable Metrics/BlockLength unless parsed_transform_step.empty? parsed_transforms << parsed_transform_step.join(Imagekitio::TransformationUtils.get_transform_delimiter) end end # rubocop:enable Metrics/BlockLength parsed_transforms.join(Imagekitio::TransformationUtils.get_chain_transform_delimiter) end |
#build_url(options) ⇒ String
Builds a URL with transformations applied
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/imagekitio/helpers/helper.rb', line 27 def build_url() # Convert model to hash - all inputs are expected to be BaseModel objects opts = .to_h # Set defaults opts[:url_endpoint] ||= "" opts[:src] ||= "" opts[:transformation_position] ||= :query return "" if opts[:src].nil? || opts[:src].empty? src = opts[:src].to_s is_absolute_url = src.start_with?("http://", "https://") begin if is_absolute_url url_obj = URI.parse(src) is_src_parameter_used_for_url = true else url_obj = URI.parse(opts[:url_endpoint].to_s) end rescue URI::InvalidURIError return "" end # Add query parameters query_params = opts[:query_parameters] || {} existing_params = CGI.parse(url_obj.query || "") query_params.each do |key, value| existing_params[key.to_s] = [value.to_s] end # Build transformation string transformation_string = build_transformation_string(opts[:transformation]) add_as_query = Imagekitio::TransformationUtils.add_as_query_parameter?(opts) || is_src_parameter_used_for_url transformation_placeholder = "PLEASEREPLACEJUSTBEFORESIGN" unless is_absolute_url # For non-absolute URLs, construct the path endpoint_path = url_obj.path path_parts = [] # Add endpoint path if it's not empty if !endpoint_path.empty? && endpoint_path != "/" path_parts << endpoint_path end if !transformation_string.empty? && !add_as_query path_parts << "#{TRANSFORMATION_PARAMETER}#{Imagekitio::TransformationUtils.get_chain_transform_delimiter}#{transformation_placeholder}" end path_parts << src url_obj.path = path_join(path_parts) end # Build query string unless existing_params.empty? url_obj.query = existing_params.map { |k, v| "#{CGI.escape(k)}=#{CGI.escape(v.first)}" }.join("&") end # Build final URL final_url = url_obj.to_s # Add transformation parameter manually to avoid URL encoding if !transformation_string.empty? && add_as_query separator = url_obj.query && !url_obj.query.empty? ? "&" : "?" final_url = "#{final_url}#{separator}#{TRANSFORMATION_PARAMETER}=#{transformation_placeholder}" end # Replace placeholder with actual transformation string unless transformation_string.empty? final_url = final_url.gsub(transformation_placeholder, transformation_string) end # Sign the URL if needed if opts[:signed] == true || (opts[:expires_in] && opts[:expires_in].to_i.positive?) = (opts[:expires_in]) url_signature = get_signature( private_key: @client.private_key, url: final_url, url_endpoint: opts[:url_endpoint].to_s, expiry_timestamp: ) # Add signature parameters final_url_uri = URI.parse(final_url) has_existing_params = final_url_uri.query && !final_url_uri.query.empty? separator = has_existing_params ? "&" : "?" if && != DEFAULT_TIMESTAMP final_url = "#{final_url}#{separator}#{TIMESTAMP_PARAMETER}=#{expiry_timestamp}" final_url = "#{final_url}&#{SIGNATURE_PARAMETER}=#{url_signature}" else final_url = "#{final_url}#{separator}#{SIGNATURE_PARAMETER}=#{url_signature}" end end final_url end |
#get_authentication_parameters(token: nil, expire: nil) ⇒ Hash{Symbol => String, Integer}
Generates authentication parameters for client-side file uploads using ImageKit’s Upload API V1.
This method creates the required authentication signature that allows secure file uploads directly from the browser or mobile applications without exposing your private API key. The generated parameters include a unique token, expiration timestamp, and HMAC signature.
237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/imagekitio/helpers/helper.rb', line 237 def get_authentication_parameters(token: nil, expire: nil) default_time_diff = 60 * 30 default_expire = Time.now.to_i + default_time_diff # Handle falsy values - empty string and nil should generate new token final_token = token.nil? || token.to_s.empty? ? generate_token : token # Handle falsy values - nil and 0 should use default expire final_expire = expire.nil? || expire.zero? ? default_expire : expire get_authentication_parameters_internal(final_token, final_expire, @client.private_key) end |
#get_responsive_image_attributes(options) ⇒ Imagekitio::Models::ResponsiveImageAttributes
Generates responsive image attributes for use in HTML <img> tags.
This method creates optimized srcset and sizes attributes for responsive images, enabling browsers to select the most appropriate image size based on the device’s screen width and resolution. Supports three strategies:
-
Width-based (w descriptors): When sizes attribute is provided
-
DPR-based (x descriptors): When width is provided without sizes
-
Fallback (w descriptors): Uses device breakpoints when neither is provided
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 |
# File 'lib/imagekitio/helpers/helper.rb', line 260 def get_responsive_image_attributes() # Convert model to hash for easier access opts = .is_a?(Imagekitio::Internal::Type::BaseModel) ? .to_h : # Default breakpoint pools default_device_breakpoints = [640, 750, 828, 1080, 1200, 1920, 2048, 3840] default_image_breakpoints = [16, 32, 48, 64, 96, 128, 256, 384] # Extract options src = opts[:src] url_endpoint = opts[:url_endpoint] width = opts[:width] sizes = opts[:sizes] device_breakpoints = opts[:device_breakpoints] || default_device_breakpoints image_breakpoints = opts[:image_breakpoints] || default_image_breakpoints transformation = opts[:transformation] || [] transformation_position = opts[:transformation_position] query_parameters = opts[:query_parameters] expires_in = opts[:expires_in] signed = opts[:signed] # Sort and merge breakpoints sorted_device_breakpoints = device_breakpoints.sort sorted_image_breakpoints = image_breakpoints.sort all_breakpoints = (sorted_image_breakpoints + sorted_device_breakpoints).sort.uniq # Compute candidate widths and descriptor kind result = compute_candidate_widths( all_breakpoints: all_breakpoints, device_breakpoints: sorted_device_breakpoints, explicit_width: width, sizes_attr: sizes ) candidates = result[:candidates] descriptor_kind = result[:descriptor_kind] # Helper to build a single ImageKit URL build_url_fn = lambda do |w| build_url( Imagekitio::Models::SrcOptions.new( src: src, url_endpoint: url_endpoint, query_parameters: query_parameters, transformation_position: transformation_position, expires_in: expires_in, signed: signed, transformation: transformation + [ Imagekitio::Models::Transformation.new(width: w, crop: "at_max") # never upscale beyond original ] ) ) end # Build srcset src_set_entries = candidates.map.with_index do |w, i| # Ensure width is an integer for proper descriptor format (e.g., "640w" not "640.0w") width_int = w.to_i descriptor = descriptor_kind == :w ? "#{width_int}w" : "#{i + 1}x" "#{build_url_fn.call(width_int)} #{descriptor}" end src_set = src_set_entries.empty? ? nil : src_set_entries.join(", ") final_sizes = sizes || (descriptor_kind == :w ? "100vw" : nil) # Build and return ResponsiveImageAttributes model Imagekitio::Models::ResponsiveImageAttributes.new( src: build_url_fn.call(candidates.last.to_i), # largest candidate as integer src_set: src_set, sizes: final_sizes, width: width ) end |