diff options
Diffstat (limited to 'src/template.c')
| -rw-r--r-- | src/template.c | 128 |
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, ¤t_len, &max_len, "{{"); + append_to_buffer(&rendered_buffer, ¤t_len, &max_len, + trimmed_tag_content); + append_to_buffer(&rendered_buffer, ¤t_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, ¤t_len, &max_len, + value_to_append); + } else { + char *escaped = html_escape(value_to_append); + if (escaped) { + append_to_buffer(&rendered_buffer, ¤t_len, &max_len, escaped); + free(escaped); + } else { + append_to_buffer(&rendered_buffer, ¤t_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, ¤t_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); |
