Skip to main content
Layers extends JSONLogic with custom operators designed for e-commerce use cases.

lower

Converts a string value to lowercase. This is useful for case-insensitive comparisons when combined with other operators like ==, startsWith, endsWith, or in. Syntax:
{
  "lower": value
}
Example: Convert an attribute value to lowercase before comparison:
{
  "==": [
    { "lower": { "var": "_attribute:vendor" } },
    "nike"
  ]
}
Edge Cases:
  • Returns null if the input is null
  • Returns an empty string if the input is an empty string
  • Returns the original value unchanged if the input is not a string (e.g., a number)
Use Cases:
  • Case-insensitive string matching in calculated attribute formulas
  • Normalizing attribute values before comparison
  • Building case-insensitive mapping rules with if/in chains

startsWith

Tests whether a string starts with a given prefix. Both arguments must be strings. Syntax:
{
  "startsWith": [string, prefix]
}
Example: Check if a product’s SKU starts with a specific prefix:
{
  "startsWith": [
    { "var": "_attribute:sku" },
    "PRE-"
  ]
}
Case-insensitive prefix matching using lower:
{
  "startsWith": [
    { "lower": { "var": "_attribute:tags.0" } },
    "sale"
  ]
}
Edge Cases:
  • Returns false if either argument is not a string
  • The comparison is case-sensitive by default — use lower for case-insensitive matching
Use Cases:
  • Categorizing products by SKU prefix
  • Matching tag patterns for calculated attribute derivation
  • Filtering products by attribute value prefixes

endsWith

Tests whether a string ends with a given suffix. Both arguments must be strings. Syntax:
{
  "endsWith": [string, suffix]
}
Example: Check if a product type ends with a specific suffix:
{
  "endsWith": [
    { "var": "_attribute:product_type" },
    "-bundle"
  ]
}
Case-insensitive suffix matching using lower:
{
  "endsWith": [
    { "lower": { "var": "_attribute:title" } },
    "gift set"
  ]
}
Edge Cases:
  • Returns false if either argument is not a string
  • The comparison is case-sensitive by default — use lower for case-insensitive matching
Use Cases:
  • Identifying bundled or grouped products by naming convention
  • Matching attribute values that follow a suffix pattern
  • Building calculated attributes based on string endings

count

Returns the count of elements in an array. Syntax:
{
  "count": array
}
Example:
{
  "count": { "var": "_raw:raw.variants" }
}
Edge Cases:
  • Returns null if the input is null or empty string
  • Returns the length of the array if valid
Use Cases:
  • Counting the number of variants in a product
  • Calculating the number of images
  • Determining the number of options available

parseDate

Parses a date string or timestamp and returns a Unix timestamp (seconds since epoch). Syntax:
{
  "parseDate": dateValue
}
Input Types:
  • String: ISO 8601 date strings, dot-separated dates (e.g., “7.26.2024”), or any format parsable by PHP’s Carbon library
  • Numeric: Unix timestamps in seconds or milliseconds (automatically normalized)
Returns: Unix timestamp in seconds, or null if the input is invalid or unparseable Examples: Parse an ISO date string:
{
  "parseDate": "2024-01-15T10:30:00Z"
}
Parse a dot-separated date (M.D.Y format):
{
  "parseDate": "7.26.2024"
}
Parse a dot-separated date (D.M.Y format):
{
  "parseDate": "26.7.2024"
}
Parse from a product attribute:
{
  "parseDate": { "var": "_attribute:published_at" }
}
Parse with fallback:
{
  "parseDate": {
    "or": [
      { "var": ["_attribute:published_at", null] },
      { "var": ["_attribute:created_at", null] }
    ]
  }
}
Dot-Separated Date Format Support: The parseDate operator supports dot-separated date formats (e.g., “7.26.2024”) with automatic disambiguation:
  • Unambiguous D.M.Y: If the first number is greater than 12, it’s interpreted as day (e.g., “26.7.2024” → July 26, 2024)
  • Unambiguous M.D.Y: If the second number is greater than 12, it’s interpreted as day (e.g., “7.26.2024” → July 26, 2024)
  • Ambiguous dates: When both numbers are ≤ 12 (e.g., “7.6.2024”), the format defaults to M.D.Y (US convention) → July 6, 2024
Edge Cases:
  • Returns null if input is null or empty string
  • Returns null for unparseable date strings (e.g., “not-a-date”) instead of throwing an exception
  • Automatically converts millisecond timestamps (> 10 digits) to seconds
  • Handles both numeric timestamps and string dates
  • Supports zero-padded dot-separated formats (e.g., “07.26.2024”)

daysSince

Calculates the number of days between a given date and the current date. Syntax:
{
  "daysSince": dateValue
}
Input Types:
  • String: Date strings (ISO 8601, dot-separated formats like “7.26.2024”, or any format parsable by PHP’s Carbon)
  • Numeric: Unix timestamps in seconds or milliseconds
  • JSONLogic expression: Output from parseDate or other date operations
Returns: Integer number of days (always positive), or null if the input is invalid or unparseable Examples: Calculate days since publication:
{
  "daysSince": { "var": "_attribute:published_at" }
}
Calculate days since a dot-separated date:
{
  "daysSince": "7.26.2024"
}
Calculate days since creation with parseDate:
{
  "daysSince": {
    "parseDate": { "var": "_attribute:created_at" }
  }
}
Calculate days since the newest variant was created:
{
  "daysSince": {
    "reduce": [
      {
        "map": [
          { "var": "_raw:raw.variants" },
          { "parseDate": { "var": "created_at" } }
        ]
      },
      {
        "if": [
          {
            "or": [
              { "==": [{ "var": "accumulator" }, null] },
              { ">": [{ "var": "current" }, { "var": "accumulator" }] }
            ]
          },
          { "var": "current" },
          { "var": "accumulator" }
        ]
      },
      null
    ]
  }
}
Dot-Separated Date Format Support: Like parseDate, the daysSince operator supports dot-separated date formats with automatic disambiguation:
  • Unambiguous D.M.Y: “26.7.2024” → July 26, 2024
  • Unambiguous M.D.Y: “7.26.2024” → July 26, 2024
  • Ambiguous dates: “7.6.2024” defaults to M.D.Y (US convention) → July 6, 2024
Edge Cases:
  • Returns null if input is null or empty string
  • Returns null for unparseable date strings (e.g., “not-a-date”) instead of throwing an exception
  • Automatically converts millisecond timestamps to seconds
  • Returns absolute value (always positive number of days)
Use Cases:
  • Product age calculations
  • Time-based merchandising rules
  • Freshness indicators for new products
  • Age-based product filtering

now

Returns the current Unix timestamp in seconds. Syntax:
{
  "now": []
}
Returns: Current Unix timestamp (seconds since epoch) Example: Calculate if a product is new (published within last 30 days):
{
  "<": [
    {
      "-": [
        { "now": [] },
        { "parseDate": { "var": "_attribute:published_at" } }
      ]
    },
    2592000
  ]
}
Use Cases:
  • Real-time date comparisons
  • Calculating time differences
  • Dynamic time-based rules