aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfrosty <gabriel@bwaaa.monster>2026-04-01 05:49:18 +0300
committerfrosty <gabriel@bwaaa.monster>2026-04-01 05:49:18 +0300
commit614bd26cb34b9b340e327d4b80927353bb5a5d0a (patch)
tree8d03df6a3f65eb13fa8d9ce8cb16cc27f46faaf2
parentc6bdeecb2a8869fd7684fc56ed0047611d327cfc (diff)
downloadomnisearch-614bd26cb34b9b340e327d4b80927353bb5a5d0a.tar.gz
refactor: internationalise pagination and clean up related code
-rw-r--r--src/Routes/Images.c56
-rw-r--r--src/Routes/Search.c123
-rw-r--r--src/Utility/Utility.c99
-rw-r--r--src/Utility/Utility.h10
-rw-r--r--static/main.css2
-rw-r--r--templates/images.html53
-rw-r--r--templates/results.html6
7 files changed, 191 insertions, 158 deletions
diff --git a/src/Routes/Images.c b/src/Routes/Images.c
index d5a1951..9d45be7 100644
--- a/src/Routes/Images.c
+++ b/src/Routes/Images.c
@@ -15,6 +15,30 @@ static char *build_images_request_cache_key(const char *query, int page,
return cache_compute_key(query, page, scope_key);
}
+static char *build_images_href(const char *query, int page) {
+ const char *safe_query = query ? query : "";
+ size_t needed = strlen("/images?q=") + strlen(safe_query) + 1;
+ if (page > 1)
+ needed += strlen("&p=") + 16;
+
+ char *href = (char *)malloc(needed);
+ if (!href)
+ return NULL;
+
+ snprintf(href, needed, "/images?q=%s", safe_query);
+ if (page > 1) {
+ char page_buf[16];
+ snprintf(page_buf, sizeof(page_buf), "%d", page);
+ strcat(href, "&p=");
+ strcat(href, page_buf);
+ }
+ return href;
+}
+
+static char *images_href_builder(int page, void *data) {
+ return build_images_href((const char *)data, page);
+}
+
int images_handler(UrlParams *params) {
extern Config global_config;
TemplateContext ctx = new_context();
@@ -33,14 +57,6 @@ int images_handler(UrlParams *params) {
}
}
- char page_str[16], prev_str[16], next_str[16], two_prev_str[16],
- two_next_str[16];
-
- snprintf(page_str, sizeof(page_str), "%d", page);
- snprintf(prev_str, sizeof(prev_str), "%d", page > 1 ? page - 1 : 0);
- snprintf(next_str, sizeof(next_str), "%d", page + 1);
- snprintf(two_prev_str, sizeof(two_prev_str), "%d", page > 2 ? page - 2 : 0);
- snprintf(two_next_str, sizeof(two_next_str), "%d", page + 2);
context_set(&ctx, "query", raw_query);
char *theme = get_theme("");
@@ -55,11 +71,15 @@ int images_handler(UrlParams *params) {
const char *error_images_msg = beaker_get_locale_value(locale, "error_images");
if (!error_images_msg) error_images_msg = "Error fetching images";
- context_set(&ctx, "page", page_str);
- context_set(&ctx, "prev_page", prev_str);
- context_set(&ctx, "next_page", next_str);
- context_set(&ctx, "two_prev_page", two_prev_str);
- context_set(&ctx, "two_next_page", two_next_str);
+ char ***pager_matrix = NULL;
+ int *pager_inner_counts = NULL;
+ int pager_count = build_pagination(page, locale, images_href_builder,
+ (void *)raw_query, &pager_matrix,
+ &pager_inner_counts);
+ if (pager_count > 0) {
+ context_set_array_of_arrays(&ctx, "pagination_links", pager_matrix,
+ pager_count, pager_inner_counts);
+ }
char *display_query = url_decode_query(raw_query);
context_set(&ctx, "query", display_query);
@@ -170,6 +190,16 @@ int images_handler(UrlParams *params) {
free(image_matrix);
free(inner_counts);
+ if (pager_count > 0) {
+ for (int i = 0; i < pager_count; i++) {
+ for (int j = 0; j < LINK_FIELD_COUNT; j++)
+ free(pager_matrix[i][j]);
+ free(pager_matrix[i]);
+ }
+ free(pager_matrix);
+ free(pager_inner_counts);
+ }
+
free_image_results(results, result_count);
free(request_cache_key);
free(display_query);
diff --git a/src/Routes/Search.c b/src/Routes/Search.c
index 9219620..e201e10 100644
--- a/src/Routes/Search.c
+++ b/src/Routes/Search.c
@@ -32,8 +32,6 @@ typedef struct {
enum {
RESULT_FIELD_COUNT = 6,
- LINK_FIELD_COUNT = 3,
- PAGER_WINDOW_SIZE = 5,
};
static InfoBox fetch_wiki_wrapper(char *query) {
@@ -189,66 +187,6 @@ static int add_infobox_to_collection(InfoBox *infobox, char ****collection,
return current_count + 1;
}
-static int add_link_to_collection(const char *href, const char *label,
- const char *class_name, char ****collection,
- int **inner_counts, int current_count) {
- char ***old_collection = *collection;
- int *old_inner_counts = *inner_counts;
- char ***new_collection =
- (char ***)malloc(sizeof(char **) * (current_count + 1));
- int *new_inner_counts =
- (int *)malloc(sizeof(int) * (current_count + 1));
-
- if (!new_collection || !new_inner_counts) {
- free(new_collection);
- free(new_inner_counts);
- return current_count;
- }
-
- if (*collection && current_count > 0) {
- memcpy(new_collection, *collection, sizeof(char **) * current_count);
- }
- if (*inner_counts && current_count > 0) {
- memcpy(new_inner_counts, *inner_counts, sizeof(int) * current_count);
- }
-
- *collection = new_collection;
- *inner_counts = new_inner_counts;
-
- (*collection)[current_count] =
- (char **)malloc(sizeof(char *) * LINK_FIELD_COUNT);
- if (!(*collection)[current_count]) {
- *collection = old_collection;
- *inner_counts = old_inner_counts;
- free(new_collection);
- free(new_inner_counts);
- return current_count;
- }
-
- (*collection)[current_count][0] = strdup(href ? href : "");
- (*collection)[current_count][1] = strdup(label ? label : "");
- (*collection)[current_count][2] = strdup(class_name ? class_name : "");
-
- if (!(*collection)[current_count][0] || !(*collection)[current_count][1] ||
- !(*collection)[current_count][2]) {
- free((*collection)[current_count][0]);
- free((*collection)[current_count][1]);
- free((*collection)[current_count][2]);
- free((*collection)[current_count]);
- *collection = old_collection;
- *inner_counts = old_inner_counts;
- free(new_collection);
- free(new_inner_counts);
- return current_count;
- }
-
- (*inner_counts)[current_count] = LINK_FIELD_COUNT;
-
- free(old_collection);
- free(old_inner_counts);
- return current_count + 1;
-}
-
static int add_warning_to_collection(const char *engine_name,
const char *warning_message,
char ****collection, int **inner_counts,
@@ -385,6 +323,16 @@ static char *build_search_href(const char *query, const char *engine_id,
return href;
}
+typedef struct {
+ const char *query;
+ const char *engine_id;
+} SearchHrefData;
+
+static char *search_href_builder(int page, void *data) {
+ SearchHrefData *d = (SearchHrefData *)data;
+ return build_search_href(d->query, d->engine_id, page);
+}
+
static char *build_search_request_cache_key(const char *query,
const char *engine_id, int page,
const char *client_key) {
@@ -436,6 +384,16 @@ int results_handler(UrlParams *params) {
snprintf(page_str, sizeof(page_str), "%d", page);
context_set(&ctx, "page", page_str);
+ char prev_str[16], next_str[16], two_prev_str[16], two_next_str[16];
+ snprintf(prev_str, sizeof(prev_str), "%d", page > 1 ? page - 1 : 0);
+ snprintf(next_str, sizeof(next_str), "%d", page + 1);
+ snprintf(two_prev_str, sizeof(two_prev_str), "%d", page > 2 ? page - 2 : 0);
+ snprintf(two_next_str, sizeof(two_next_str), "%d", page + 2);
+ context_set(&ctx, "prev_page", prev_str);
+ context_set(&ctx, "next_page", next_str);
+ context_set(&ctx, "two_prev_page", two_prev_str);
+ context_set(&ctx, "two_next_page", two_next_str);
+
if (!raw_query || strlen(raw_query) == 0) {
send_redirect("/");
free_context(&ctx);
@@ -810,43 +768,10 @@ int results_handler(UrlParams *params) {
char ***pager_matrix = NULL;
int *pager_inner_counts = NULL;
- int pager_count = 0;
- int pager_start = page <= 3 ? 1 : page - 2;
- int pager_end = pager_start + PAGER_WINDOW_SIZE - 1;
-
- if (page > 3) {
- char *first_href = build_search_href(raw_query, selected_engine_id, 1);
- pager_count = add_link_to_collection(first_href, "First", "pagination-btn",
- &pager_matrix, &pager_inner_counts,
- pager_count);
- free(first_href);
- }
-
- if (page > 1) {
- char *prev_href =
- build_search_href(raw_query, selected_engine_id, page - 1);
- pager_count = add_link_to_collection(prev_href, "Prev", "pagination-btn",
- &pager_matrix, &pager_inner_counts,
- pager_count);
- free(prev_href);
- }
-
- for (int i = pager_start; i <= pager_end; i++) {
- char label[16];
- snprintf(label, sizeof(label), "%d", i);
- char *page_href = build_search_href(raw_query, selected_engine_id, i);
- pager_count = add_link_to_collection(
- page_href, label,
- i == page ? "pagination-btn pagination-current" : "pagination-btn",
- &pager_matrix, &pager_inner_counts, pager_count);
- free(page_href);
- }
-
- char *next_href = build_search_href(raw_query, selected_engine_id, page + 1);
- pager_count = add_link_to_collection(next_href, "Next", "pagination-btn",
- &pager_matrix, &pager_inner_counts,
- pager_count);
- free(next_href);
+ SearchHrefData href_data = { .query = raw_query, .engine_id = selected_engine_id };
+ int pager_count = build_pagination(page, locale, search_href_builder,
+ &href_data, &pager_matrix,
+ &pager_inner_counts);
if (pager_count > 0) {
context_set_array_of_arrays(&ctx, "pagination_links", pager_matrix,
diff --git a/src/Utility/Utility.c b/src/Utility/Utility.c
index 0d7a28e..bffda4d 100644
--- a/src/Utility/Utility.c
+++ b/src/Utility/Utility.c
@@ -1,5 +1,6 @@
#include "Utility.h"
#include <beaker.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -32,3 +33,101 @@ char *get_locale(const char *default_locale) {
free(cookie);
return strdup(default_locale);
}
+
+int add_link_to_collection(const char *href, const char *label,
+ const char *class_name, char ****collection,
+ int **inner_counts, int current_count) {
+ char ***old_collection = *collection;
+ int *old_inner_counts = *inner_counts;
+ char ***new_collection =
+ (char ***)malloc(sizeof(char **) * (current_count + 1));
+ int *new_inner_counts =
+ (int *)malloc(sizeof(int) * (current_count + 1));
+
+ if (!new_collection || !new_inner_counts) {
+ free(new_collection);
+ free(new_inner_counts);
+ return current_count;
+ }
+
+ if (*collection && current_count > 0) {
+ memcpy(new_collection, *collection, sizeof(char **) * current_count);
+ }
+ if (*inner_counts && current_count > 0) {
+ memcpy(new_inner_counts, *inner_counts, sizeof(int) * current_count);
+ }
+
+ *collection = new_collection;
+ *inner_counts = new_inner_counts;
+
+ (*collection)[current_count] =
+ (char **)malloc(sizeof(char *) * LINK_FIELD_COUNT);
+ if (!(*collection)[current_count]) {
+ *collection = old_collection;
+ *inner_counts = old_inner_counts;
+ free(new_collection);
+ free(new_inner_counts);
+ return current_count;
+ }
+
+ (*collection)[current_count][0] = strdup(href ? href : "");
+ (*collection)[current_count][1] = strdup(label ? label : "");
+ (*collection)[current_count][2] = strdup(class_name ? class_name : "");
+
+ if (!(*collection)[current_count][0] || !(*collection)[current_count][1] ||
+ !(*collection)[current_count][2]) {
+ free((*collection)[current_count][0]);
+ free((*collection)[current_count][1]);
+ free((*collection)[current_count][2]);
+ free((*collection)[current_count]);
+ *collection = old_collection;
+ *inner_counts = old_inner_counts;
+ free(new_collection);
+ free(new_inner_counts);
+ return current_count;
+ }
+
+ (*inner_counts)[current_count] = LINK_FIELD_COUNT;
+
+ free(old_collection);
+ free(old_inner_counts);
+ return current_count + 1;
+}
+
+int build_pagination(int page, const char *locale,
+ char *(*href_builder)(int page, void *data), void *data,
+ char ****out_matrix, int **out_inner_counts) {
+ enum { PAGER_WINDOW_SIZE = 5 };
+
+ *out_matrix = NULL;
+ *out_inner_counts = NULL;
+ int count = 0;
+
+ int pager_start = page <= 3 ? 1 : page - 2;
+ int pager_end = pager_start + PAGER_WINDOW_SIZE - 1;
+
+ if (page > 1) {
+ char *href = href_builder(page - 1, data);
+ count = add_link_to_collection(href, "<", "pagination-btn prev",
+ out_matrix, out_inner_counts, count);
+ free(href);
+ }
+
+ for (int i = pager_start; i <= pager_end; i++) {
+ char label[16];
+ snprintf(label, sizeof(label), "%d", i);
+ char *href = href_builder(i, data);
+ count = add_link_to_collection(
+ href, label,
+ i == page ? "pagination-btn pagination-current" : "pagination-btn",
+ out_matrix, out_inner_counts, count);
+ free(href);
+ }
+
+ char *href = href_builder(page + 1, data);
+ count = add_link_to_collection(href, ">", "pagination-btn next",
+ out_matrix, out_inner_counts, count);
+ free(href);
+
+ return count;
+}
diff --git a/src/Utility/Utility.h b/src/Utility/Utility.h
index 387aae0..3863bc2 100644
--- a/src/Utility/Utility.h
+++ b/src/Utility/Utility.h
@@ -3,8 +3,18 @@
#include <beaker.h>
+#define LINK_FIELD_COUNT 3
+
int hex_to_int(char c);
char *get_theme(const char *default_theme);
char *get_locale(const char *default_locale);
+int add_link_to_collection(const char *href, const char *label,
+ const char *class_name, char ****collection,
+ int **inner_counts, int current_count);
+
+int build_pagination(int page, const char *locale,
+ char *(*href_builder)(int page, void *data), void *data,
+ char ****out_matrix, int **out_inner_counts);
+
#endif
diff --git a/static/main.css b/static/main.css
index 6994ade..f60c566 100644
--- a/static/main.css
+++ b/static/main.css
@@ -927,3 +927,5 @@ header .logo-link:hover {
flex-direction: column;
}
}
+
+
diff --git a/templates/images.html b/templates/images.html
index f4522aa..9fd0584 100644
--- a/templates/images.html
+++ b/templates/images.html
@@ -65,49 +65,16 @@
</div>
{{endfor}}
</div>
- <nav class="pagination">
- <a class="pagination-btn prev" href="/images?q={{query}}&p={{prev_page}}">
- &larr;
- </a>
-
- {{if two_prev_page != 0}}
- <a class="pagination-btn prev" href="/images?q={{query}}&p={{two_prev_page}}">
- {{two_prev_page}}
- </a>
- {{endif}}
-
- {{if prev_page != 0}}
- <a class="pagination-btn prev" href="/images?q={{query}}&p={{prev_page}}">
- {{prev_page}}
- </a>
- {{endif}}
-
- <a class="pagination-btn pagination-current" href="/images?q={{query}}&p={{page}}">
- {{page}}
- </a>
- <a class="pagination-btn next" href="/images?q={{query}}&p={{next_page}}">
- {{next_page}}
- </a>
- <a class="pagination-btn next" href="/images?q={{query}}&p={{two_next_page}}">
- {{two_next_page}}
- </a>
-
- {{if prev_page == 0}}
- <a class="pagination-btn prev" href="/images?q={{query}}&p=4">
- 4
- </a>
- {{endif}}
-
- {{if two_prev_page == 0}}
- <a class="pagination-btn prev" href="/images?q={{query}}&p=5">
- 5
- </a>
- {{endif}}
- <a class="pagination-btn next" href="/images?q={{query}}&p={{next_page}}">
- &rarr;
- </a>
- </nav>
+ {{if exists pagination_links}}
+ <nav class="pagination">
+ {{for link in pagination_links}}
+ <a class="{{link[2]}}" href="{{link[0]}}">
+ {{link[1]}}
+ </a>
+ {{endfor}}
+ </nav>
+ {{endif}}
</main>
</body>
-</html>
+</html> \ No newline at end of file
diff --git a/templates/results.html b/templates/results.html
index 4ce7496..54ac195 100644
--- a/templates/results.html
+++ b/templates/results.html
@@ -118,8 +118,8 @@
{{info[2]|safe}}
</p>
<a class="read-more" href="{{info[3]}}">
- {{l("read_more")}}
- </a>
+ {{l("read_more")}}
+ </a>
</div>
</div>
</section>
@@ -129,4 +129,4 @@
</div>
</body>
-</html>
+</html> \ No newline at end of file