aboutsummaryrefslogtreecommitdiff
path: root/src/template.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/template.c')
-rw-r--r--src/template.c128
1 files changed, 124 insertions, 4 deletions
diff --git a/src/template.c b/src/template.c
index 76e8662..6255d1b 100644
--- a/src/template.c
+++ b/src/template.c
@@ -1,4 +1,5 @@
#include "../beaker.h"
+#include "beaker_globals.h"
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
@@ -530,6 +531,7 @@ typedef struct {
ConditionType type;
char var_name[MAX_KEY_LEN];
char compare_value[MAX_VALUE_LEN];
+ int compare_index;
bool negate;
} Condition;
@@ -564,11 +566,45 @@ static bool evaluate_condition(const Condition *cond, TemplateContext *ctx) {
return cond->negate ? !exists : exists;
}
- case CONDITION_EQUAL:
- return (strcmp(var_value, cond->compare_value) == 0);
+ case CONDITION_EQUAL: {
+ const char *compare_value = cond->compare_value;
+ char compare_buf[MAX_VALUE_LEN];
+ ContextVar *compare_var = find_context_var(ctx, cond->compare_value);
+ if (cond->compare_index >= 0) {
+ if (compare_var != NULL &&
+ compare_var->type == CONTEXT_TYPE_STRING_ARRAY &&
+ cond->compare_index >= 0 &&
+ cond->compare_index < compare_var->value.string_array_data.count) {
+ compare_value = compare_var->value.string_array_data
+ .values[cond->compare_index];
+ }
+ } else if (compare_var != NULL && compare_var->type == CONTEXT_TYPE_STRING) {
+ strncpy(compare_buf, compare_var->value.string_val, MAX_VALUE_LEN - 1);
+ compare_buf[MAX_VALUE_LEN - 1] = '\0';
+ compare_value = compare_buf;
+ }
+ return (strcmp(var_value, compare_value) == 0);
+ }
- case CONDITION_NOT_EQUAL:
- return (strcmp(var_value, cond->compare_value) != 0);
+ case CONDITION_NOT_EQUAL: {
+ const char *compare_value = cond->compare_value;
+ char compare_buf[MAX_VALUE_LEN];
+ ContextVar *compare_var = find_context_var(ctx, cond->compare_value);
+ if (cond->compare_index >= 0) {
+ if (compare_var != NULL &&
+ compare_var->type == CONTEXT_TYPE_STRING_ARRAY &&
+ cond->compare_index >= 0 &&
+ cond->compare_index < compare_var->value.string_array_data.count) {
+ compare_value = compare_var->value.string_array_data
+ .values[cond->compare_index];
+ }
+ } else if (compare_var != NULL && compare_var->type == CONTEXT_TYPE_STRING) {
+ strncpy(compare_buf, compare_var->value.string_val, MAX_VALUE_LEN - 1);
+ compare_buf[MAX_VALUE_LEN - 1] = '\0';
+ compare_value = compare_buf;
+ }
+ return (strcmp(var_value, compare_value) != 0);
+ }
default:
return false;
@@ -580,6 +616,7 @@ static Condition parse_condition(const char *condition_str) {
cond.type = CONDITION_NONE;
cond.var_name[0] = '\0';
cond.compare_value[0] = '\0';
+ cond.compare_index = -1;
cond.negate = false;
if (condition_str == NULL || *condition_str == '\0') {
@@ -707,6 +744,15 @@ static Condition parse_condition(const char *condition_str) {
end--;
}
+ char *bracket = strchr(cond.compare_value, '[');
+ if (bracket != NULL) {
+ char *close_bracket = strchr(bracket, ']');
+ if (close_bracket != NULL) {
+ *bracket = '\0';
+ cond.compare_index = atoi(bracket + 1);
+ }
+ }
+
return cond;
}
@@ -1184,6 +1230,80 @@ static char *render_template_segment(const char *template_segment,
}
}
+ else if (strncmp(trimmed_tag_content, "l(\"", 3) == 0) {
+ const char *key_start = trimmed_tag_content + 3;
+ const char *key_end = strstr(key_start, "\")");
+ if (key_end == NULL) {
+ fprintf(stderr,
+ "[ERROR] render_template_segment: Malformed l() tag '%s'. "
+ "Expected l(\"key\"). Appending as-is.\n",
+ trimmed_tag_content);
+ append_to_buffer(&rendered_buffer, &current_len, &max_len, "{{");
+ append_to_buffer(&rendered_buffer, &current_len, &max_len,
+ trimmed_tag_content);
+ append_to_buffer(&rendered_buffer, &current_len, &max_len, "}}");
+ free(tag_content_raw);
+ current_pos = end_tag + 2;
+ continue;
+ }
+
+ size_t key_len = key_end - key_start;
+ char l10n_key[MAX_KEY_LEN];
+ if (key_len >= MAX_KEY_LEN) key_len = MAX_KEY_LEN - 1;
+ strncpy(l10n_key, key_start, key_len);
+ l10n_key[key_len] = '\0';
+
+ bool is_safe = false;
+ const char *after_close = key_end + 2;
+ if (strncmp(after_close, "|safe", 5) == 0) {
+ is_safe = true;
+ }
+
+ const char *value_to_append = NULL;
+
+ ContextVar *locale_var = find_context_var(ctx, "__locale");
+ if (locale_var != NULL && locale_var->type == CONTEXT_TYPE_STRING) {
+ const char *current_locale_id = locale_var->value.string_val;
+ for (int i = 0; i < locale_count; i++) {
+ if (strcmp(locales[i].meta.id, current_locale_id) == 0) {
+ for (int j = 0; j < locales[i].key_count; j++) {
+ if (strcmp(locales[i].keys[j].key, l10n_key) == 0) {
+ value_to_append = locales[i].keys[j].value;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ if (value_to_append != NULL) {
+ if (is_safe) {
+ append_to_buffer(&rendered_buffer, &current_len, &max_len,
+ value_to_append);
+ } else {
+ char *escaped = html_escape(value_to_append);
+ if (escaped) {
+ append_to_buffer(&rendered_buffer, &current_len, &max_len, escaped);
+ free(escaped);
+ } else {
+ append_to_buffer(&rendered_buffer, &current_len, &max_len,
+ value_to_append);
+ }
+ }
+ } else {
+ fprintf(stderr,
+ "[WARNING] render_template_segment: l10n key '%s' not found "
+ "for current locale. Appending key as-is.\n",
+ l10n_key);
+ append_to_buffer(&rendered_buffer, &current_len, &max_len, l10n_key);
+ }
+
+ free(tag_content_raw);
+ current_pos = end_tag + 2;
+ continue;
+ }
+
else {
bool is_safe = false;
char *processing_tag_content = strdup(trimmed_tag_content);