Skip to content

Instantly share code, notes, and snippets.

@steveosoule
Last active July 6, 2022 17:30
Show Gist options
  • Select an option

  • Save steveosoule/85ea4fd4c46e79c4e1acb253e09d9833 to your computer and use it in GitHub Desktop.

Select an option

Save steveosoule/85ea4fd4c46e79c4e1acb253e09d9833 to your computer and use it in GitHub Desktop.
Miva - Sort Facets Numerically
<mvt:comment>
# Sort Some Facets Numerically
Miva's facets are often sorted in a method that users do not expect for numerical values, so this is an attempt to make them display in true numerical order.
## Algorithm
Instead of sorting by facet_value:prompt, we create a seperate memeber to perform the QuickSortArray on: :sort_value
:sort_value starts as the prompt and then is modified/normalized as follows:
- Strips non-numerical characters
- Converts fractions to decimals
- Pads the number left more than the total number of digits
- Then it is QuickSortArray'd on the :sort_value
## Instructions for Use
1. Modify the l.NUMERICAL_FACET_CODES variable to match the facet:code that you want to enact this sort logic on
2. Modify l.SEARCHES with any units and additional non-numerical content that might be present in your facet_value:prompt
3. Update l.REPLACEMENTS to match the number of items in l.SEARCHES
4. Add this to the "Facets Layout" right before the standard `facets:facets` foreach loop
</mvt:comment>
<mvt:comment>Constants</mvt:comment>
<mvt:assign name="l.MAX_DIGITS" value="10" />
<mvt:assign name="l.result" value="miva_splitstring( 'length,width,diameter,area', ',', l.NUMERICAL_FACET_CODES, 'trim' )" />
<mvt:assign name="l.result" value="miva_splitstring( '-|ft.|ft|in.|in|cm.|cm|mm.|mm|,', '|', l.SEARCHES, 'trim' )" />
<mvt:assign name="l.result" value="miva_splitstring( '|||||||||', '|', l.REPLACEMENTS, 'trim' )" />
<mvt:foreach iterator="facet" array="facets:facets">
<mvt:assign name="l.settings:facet:is_numerical" value="miva_array_find( l.settings:facet:code, l.NUMERICAL_FACET_CODES, 1 ) GT 0" />
<mvt:if expr="l.settings:facet:is_numerical">
<mvt:comment>Clean/Normalize sort_value</mvt:comment>
<mvt:foreach iterator="facet_value" array="facet:values">
<mvt:assign name="l.is_negative" value="('-' IN l.settings:facet_value:prompt) EQ 1" />
<mvt:comment>Clean Prompt</mvt:comment>
<mvt:assign name="l.settings:facet_value:sort_value" value="glosub_array( l.settings:facet_value:prompt, l.SEARCHES, l.REPLACEMENTS )" />
<mvt:comment>Convert fractions to decimals</mvt:comment>
<mvt:assign name="l.integer" value="gettoken( l.settings:facet_value:sort_value, ' ', 1 )" />
<mvt:assign name="l.fraction" value="gettoken( l.settings:facet_value:sort_value, ' ', 2 )" />
<mvt:if expr="ISNULL l.fraction AND '/' IN l.integer">
<mvt:assign name="l.fraction" value="l.integer" />
<mvt:assign name="l.integer" value="''" />
</mvt:if>
<mvt:if expr="NOT ISNULL l.fraction">
<mvt:assign name="l.numerator" value="gettoken( l.fraction, '/', 1 )" />
<mvt:assign name="l.denominator" value="gettoken( l.fraction, '/', 2 )" />
<mvt:assign name="l.settings:facet_value:sort_value" value="l.integer + (l.numerator / l.denominator)" />
</mvt:if>
<mvt:comment>
Pad value with leading zeros so sort works as you'd expect numerically
</mvt:comment>
<mvt:assign name="l.settings:facet_value:sort_value" value="padl( trim(l.settings:facet_value:sort_value), l.MAX_DIGITS, '0' )" />
<mvt:comment>Re-add the negative that was glosub'd out earlier</mvt:comment>
<mvt:if expr="l.is_negative">
<mvt:assign name="l.settings:facet_value:sort_value" value="'-' $ l.settings:facet_value:sort_value" />
</mvt:if>
</mvt:foreach>
<mvt:comment>Sort by our custom/numeric :sort_value</mvt:comment>
<mvt:do file="g.Module_Library_Utilities" name="l.success" value="QuickSortArray( l.settings:facet:values, ':sort_value', 1 )" />
</mvt:if>
</<mvt:foreach>
Input/Prompt Output/Sort
-10,000 -0000010000
-2,000 3/4 in. -0002000.75
-2,000.5 in. -00002000.5
-100.1 in. -00000100.1
-100 -0000000100
-1 in. -0000000001
-0.75 in. -0000000.75
-0.1 in. -00000000.1
0 in. 0000000000
0.1 in. 00000000.1
1/4 in. 0000000.25
0.25 in. 0000000.25
0.25 0000000.25
1/2 in. 00000000.5
0.5 00000000.5
0.5 in. 00000000.5
0.75 in. 0000000.75
3/4 in. 0000000.75
1 in. 0000000001
1 0000000001
1.5 00000001.5
1 1/2 in. 00000001.5
1 3/4 in. 0000001.75
2 in 0000000002
2 1/2 in. 00000002.5
4.5 00000004.5
10 in 0000000010
10 in. 0000000010
10 0000000010
10.1 00000010.1
10 1/4 in. 0000010.25
10 1/2 in. 00000010.5
10.9 00000010.9
20 0000000020
20 in. 0000000020
20 1/4 in. 0000020.25
20 1/2 in. 00000020.5
100 in. 0000000100
100.1 00000100.1
100.2 00000100.2
100 1/4 in. 0000100.25
100.3 00000100.3
100.5 00000100.5
100 1/2 in. 00000100.5
1000 0000001000
1000.1 00001000.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment