+try:
+  from urllib.parse import quote
+except ImportError:
+  from urllib import quote
+
 from sqlobject.sqlbuilder import AND, OR, func, CONCAT
 
 from .config import get_config
     return not value.islower()
 
 
-def search_authors_raw(value, search_type, case_sensitive):
+def search_authors_raw(value, search_type, case_sensitive, sort=None):
     value = decode(value)
     if not search_type:
         search_type = 'start'
         CONCAT(Author.q.surname, ' ', Author.q.name, ' ', Author.q.misc_name),
         decode(value)
     )]
-    authors = search_authors(search_type, case_sensitive, {}, expressions,
-                             orderBy=('surname', 'name', 'misc_name'))
     columns = get_config().getlist('columns', 'author', ['fullname'])
+    orderby_columns = columns[:]
+    try:
+        idx = orderby_columns.index('fullname')
+    except ValueError:
+        pass
+    else:
+        orderby_columns[idx:idx+1] = ('surname', 'name', 'misc_name')
+    if sort:
+        if sort[0] in '+-':
+            sort_order = sort[0]
+            sort_key = sort[1:]
+        else:
+            sort_order = '+'
+            sort_key = sort
+            sort = sort_order+sort_key
+        if sort_key == 'fullname':
+            orderby_columns = (sort_order+'surname',
+                               sort_order+'name', sort_order+'misc_name')
+        elif sort_key == 'count':
+            orderby_columns = (sort_order+'count', sort_order+'surname',
+                               sort_order+'name', sort_order+'misc_name')
+        else:
+            orderby_columns = [sort_order+sort_key]
+    else:
+        sort = '+' + columns[0]
+    authors = search_authors(search_type, case_sensitive, {}, expressions,
+                             orderBy=orderby_columns)
     return {
         'authors': list(authors),
         'search_authors': value,
         'search_type': search_type,
         'case_sensitive': case_sensitive,
         'columns': columns,
+        'sort': sort,
+        'quote': quote,
     }
 
 
 
 currentTime=time.time
 __CHEETAH_version__ = '3.3.1'
 __CHEETAH_versionTuple__ = (3, 3, 1, 'final', 0)
-__CHEETAH_genTime__ = 1718725815.054143
-__CHEETAH_genTimestamp__ = 'Tue Jun 18 18:50:15 2024'
+__CHEETAH_genTime__ = 1720485596.472826
+__CHEETAH_genTimestamp__ = 'Tue Jul  9 03:39:56 2024'
 __CHEETAH_src__ = 'list_authors.tmpl'
-__CHEETAH_srcLastModified__ = 'Tue Jun 18 18:50:12 2024'
+__CHEETAH_srcLastModified__ = 'Tue Jul  9 03:39:54 2024'
 __CHEETAH_docstring__ = 'Autogenerated by Cheetah: The Python-Powered Template Engine'
 
 if __CHEETAH_versionTuple__ < RequiredCheetahVersionTuple:
 
 ''')
         if VFFSL(SL,"authors",True): # generated from line 12, col 1
-            _orig_filter_63533534 = _filter
+            _orig_filter_20064572 = _filter
             filterName = u'WebSafe'
             if "WebSafe" in self._CHEETAH__filters:
                 _filter = self._CHEETAH__currentFilter = self._CHEETAH__filters[filterName]
                     _(VFFSL(SL,"column",True))
                 _v = VFFSL(SL,"_",False)(VFFSL(SL,"column",True)) # u'$_($column)' on line 18, col 36
                 if _v is not None: write(_filter(_v, rawExpr=u'$_($column)')) # from line 18, col 36.
-                write(u'''</td>
+                write(u'''
+''')
+                if VFFSL(SL,"sort",True) in (VFFSL(SL,"column",True), '+'+VFFSL(SL,"column",True), '-'+VFFSL(SL,"column",True)): # generated from line 19, col 5
+                    if VFFSL(SL,"sort",True) in (VFFSL(SL,"column",True), '+'+VFFSL(SL,"column",True)): # generated from line 20, col 7
+                        sort_param = '-'+VFFSL(SL,"column",True)
+                        sort_sign = '↓'
+                    elif VFFSL(SL,"sort",True) == '-'+VFFSL(SL,"column",True): # generated from line 23, col 7
+                        sort_param = VFFSL(SL,"quote",False)('+')+VFFSL(SL,"column",True)
+                        sort_sign = '↑'
+                else: # generated from line 27, col 5
+                    sort_param = VFFSL(SL,"quote",False)('+')+VFFSL(SL,"column",True)
+                    sort_sign = '↓'
+                case_param = '1' if VFFSL(SL,"case_sensitive",True) else ''
+                write(u'''    <a href="/list_authors/?search_authors=''')
+                _v = VFFSL(SL,"search_authors",True) # u'$search_authors' on line 32, col 44
+                if _v is not None: write(_filter(_v, rawExpr=u'$search_authors')) # from line 32, col 44.
+                write(u'''&search_type=''')
+                _v = VFFSL(SL,"search_type",True) # u'$search_type' on line 32, col 72
+                if _v is not None: write(_filter(_v, rawExpr=u'$search_type')) # from line 32, col 72.
+                write(u'''&case_sensitive=''')
+                _v = VFFSL(SL,"case_param",True) # u'$case_param' on line 32, col 100
+                if _v is not None: write(_filter(_v, rawExpr=u'$case_param')) # from line 32, col 100.
+                write(u'''&sort=''')
+                _v = VFFSL(SL,"sort_param",True) # u'$sort_param' on line 32, col 117
+                if _v is not None: write(_filter(_v, rawExpr=u'$sort_param')) # from line 32, col 117.
+                write(u'''">''')
+                _v = VFFSL(SL,"sort_sign",True) # u'$sort_sign' on line 32, col 130
+                if _v is not None: write(_filter(_v, rawExpr=u'$sort_sign')) # from line 32, col 130.
+                write(u'''</a>
+    </td>
 ''')
             write(u'''  </tr>
 ''')
-            for author in VFFSL(SL,"authors",True): # generated from line 21, col 3
+            for author in VFFSL(SL,"authors",True): # generated from line 36, col 3
                 write(u'''  <tr>
 ''')
-                for column in VFFSL(SL,"columns",True): # generated from line 23, col 3
-                    if VFFSL(SL,"column",True) == 'count': # generated from line 24, col 5
+                for column in VFFSL(SL,"columns",True): # generated from line 38, col 3
+                    if VFFSL(SL,"column",True) == 'count': # generated from line 39, col 5
                         style = ' style="text-align: right; width: 5ex"'
-                    else: # generated from line 26, col 5
+                    else: # generated from line 41, col 5
                         style = ''
                     write(u'''    <td''')
-                    _v = VFFSL(SL,"style",True) # u'$style' on line 29, col 8
-                    if _v is not None: write(_filter(_v, rawExpr=u'$style')) # from line 29, col 8.
+                    _v = VFFSL(SL,"style",True) # u'$style' on line 44, col 8
+                    if _v is not None: write(_filter(_v, rawExpr=u'$style')) # from line 44, col 8.
                     write(u'''><a href="/books-by-author/''')
-                    _v = VFFSL(SL,"author.id",True) # u'$author.id' on line 29, col 41
-                    if _v is not None: write(_filter(_v, rawExpr=u'$author.id')) # from line 29, col 41.
+                    _v = VFFSL(SL,"author.id",True) # u'$author.id' on line 44, col 41
+                    if _v is not None: write(_filter(_v, rawExpr=u'$author.id')) # from line 44, col 41.
                     write(u'''/">
     ''')
-                    _v = VFFSL(SL,"unicode",False)(VFFSL(SL,"getattr",False)(VFFSL(SL,"author",True), VFFSL(SL,"column",True)) or '') # u"$unicode($getattr($author, $column) or '')" on line 30, col 5
-                    if _v is not None: write(_filter(_v, rawExpr=u"$unicode($getattr($author, $column) or '')")) # from line 30, col 5.
+                    _v = VFFSL(SL,"unicode",False)(VFFSL(SL,"getattr",False)(VFFSL(SL,"author",True), VFFSL(SL,"column",True)) or '') # u"$unicode($getattr($author, $column) or '')" on line 45, col 5
+                    if _v is not None: write(_filter(_v, rawExpr=u"$unicode($getattr($author, $column) or '')")) # from line 45, col 5.
                     write(u'''
     </a></td>
 ''')
 ''')
             write(u'''  </table>
 ''')
-            _filter = self._CHEETAH__currentFilter = _orig_filter_63533534
-        else: # generated from line 37, col 1
+            _filter = self._CHEETAH__currentFilter = _orig_filter_20064572
+        else: # generated from line 52, col 1
             write(u'''  <p>\u041d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e \u043d\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0430\u0432\u0442\u043e\u0440\u0430!</p>
 ''')