Yes, that's seems the only way ...
I defined 3 arrays to have optional sorting or not:
<!-- getting parameters from url -->
{% assign order = request.params['order'] | default: 'cr847_name' %}
{% assign orderdir = request.params['orderdir'] | default: 'ASC' %}
<!-- use orderir in fetch query -->
<!-- entity columns/attributes themeselves -->
{% assign columns = "cr847_firstname,cr847_name,cr847_city" | split:"," %}
<!-- Header names -->
{% assign colnames = "Firstname,Name,City" | split:"," %}
<!-- Sortable headers. Note: 'x' is neccessary for index counting. firstname is not sortable -->
{% assign sortAttributes = "x,cr847_name,cr847_city" | split:"," %}
<table class="table">
<thead>
<tr>
{% for col in columns %}
<th data-logicalname="{{ col }}}">
<!-- if column is sortable add a link -->
{% if columns[forloop.index0] == sortAttributes[forloop.index0] %}
<a href="{{ request.path_and_query | add_query:'order', sortAttributes[forloop.index0] | add_query: 'orderdir', orderdir}}">
{{ colnames[forloop.index0] }}
{% if order==sortAttributes[forloop.index0] %}
{{ orderdir_icon }}
{% else %}
{{order}}!={{sortAttributes[forloop.index0]}}
{% endif %}
</a>
{% else %}
{{ colnames[forloop.index0] }}
{% endif %}
</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for result in query.results.entities %}
<tr>
...
Have fun,
AndKan.