update: csrf_token and lorem
This commit is contained in:
parent
bbab647430
commit
b09da93f0d
3 changed files with 175 additions and 3 deletions
|
|
@ -19,6 +19,14 @@ pub const NodeType = enum {
|
|||
cycle,
|
||||
firstof,
|
||||
load,
|
||||
csrf_token,
|
||||
lorem,
|
||||
};
|
||||
|
||||
pub const LoremNode = struct {
|
||||
count: ?[]const u8 = null, // "3" ou null
|
||||
method: ?[]const u8 = null, // "p" ou "w" ou null
|
||||
format: ?[]const u8 = null, // "html" ou null
|
||||
};
|
||||
|
||||
pub const LoadNode = struct {
|
||||
|
|
@ -147,6 +155,8 @@ pub const Node = struct {
|
|||
cycle: ?CycleNode = null,
|
||||
firstof: ?FirstOfNode = null,
|
||||
load: ?LoadNode = null,
|
||||
lorem: ?LoremNode = null,
|
||||
csrf_token: bool = false,
|
||||
|
||||
pub fn deinit(self: Node, allocator: std.mem.Allocator) void {
|
||||
switch (self.type) {
|
||||
|
|
@ -235,6 +245,12 @@ pub const Node = struct {
|
|||
for (l.libraries) |lib| allocator.free(lib);
|
||||
allocator.free(l.libraries);
|
||||
},
|
||||
.csrf_token => {},
|
||||
.lorem => if (self.lorem) |l| {
|
||||
if (l.count) |c| allocator.free(c);
|
||||
if (l.method) |m| allocator.free(m);
|
||||
if (l.format) |f| allocator.free(f);
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -1090,6 +1106,48 @@ pub const Parser = struct {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, tag_name, "lorem")) {
|
||||
const args = node.tag.?.args;
|
||||
|
||||
var count: ?[]const u8 = null;
|
||||
var method: ?[]const u8 = null;
|
||||
var format: ?[]const u8 = null;
|
||||
|
||||
var parts = std.mem.splitScalar(u8, args, ' ');
|
||||
while (parts.next()) |part| {
|
||||
const trimmed = std.mem.trim(u8, part, " \t\r\n");
|
||||
if (trimmed.len == 0) continue;
|
||||
|
||||
const num: usize = std.fmt.parseInt(usize, trimmed, 10) catch 0;
|
||||
if (num > 0) {
|
||||
std.debug.print("trimmed: {s}\n", .{trimmed});
|
||||
count = try allocator.dupe(u8, trimmed);
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, trimmed, "p") or std.mem.eql(u8, trimmed, "w")) {
|
||||
std.debug.print("trimmed: {s}\n", .{trimmed});
|
||||
method = try allocator.dupe(u8, trimmed);
|
||||
} else if (std.mem.eql(u8, trimmed, "html")) {
|
||||
std.debug.print("trimmed: {s}\n", .{trimmed});
|
||||
format = try allocator.dupe(u8, trimmed);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
allocator.free(node.tag.?.name);
|
||||
allocator.free(node.tag.?.args);
|
||||
|
||||
try list.append(allocator, Node{
|
||||
.type = .lorem,
|
||||
.lorem = .{
|
||||
.count = count,
|
||||
.method = method,
|
||||
.format = format,
|
||||
},
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, tag_name, "filter")) {
|
||||
const filters_raw = node.tag.?.args;
|
||||
const raw_open = node.tag.?.raw;
|
||||
|
|
@ -1457,6 +1515,25 @@ pub const Parser = struct {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, tag_name, "csrf_token")) {
|
||||
// Verifica se tem argumentos (não deve ter)
|
||||
if (node.tag.?.args.len > 0 and !std.mem.allEqual(u8, node.tag.?.args, ' ')) {
|
||||
return error.InvalidCsrfTokenArgs;
|
||||
}
|
||||
|
||||
allocator.free(node.tag.?.name);
|
||||
allocator.free(node.tag.?.args);
|
||||
|
||||
std.debug.print("3.0 - na real sou um csrf_token\n", .{});
|
||||
std.debug.print("===================================\n", .{});
|
||||
|
||||
try list.append(allocator, Node{
|
||||
.type = .csrf_token,
|
||||
.csrf_token = true,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
// Para tags normais
|
||||
std.debug.print("===================================\n", .{});
|
||||
try list.append(allocator, node);
|
||||
|
|
|
|||
|
|
@ -643,3 +643,69 @@ test "parse load com múltiplas" {
|
|||
try testing.expectEqualStrings("admin_urls", l.libraries[0]);
|
||||
try testing.expectEqualStrings("static", l.libraries[1]);
|
||||
}
|
||||
|
||||
test "parse csrf_token simples" {
|
||||
const allocator = testing.allocator;
|
||||
const template = "<form>{% csrf_token %}</form>";
|
||||
const nodes = try parser.parse(allocator, template);
|
||||
defer {
|
||||
for (nodes) |node| node.deinit(allocator);
|
||||
allocator.free(nodes);
|
||||
}
|
||||
|
||||
try testing.expectEqual(@as(usize, 3), nodes.len);
|
||||
try testing.expect(nodes[0].type == .text);
|
||||
try testing.expectEqualStrings("<form>", nodes[0].text.?.content);
|
||||
|
||||
try testing.expect(nodes[1].type == .csrf_token);
|
||||
|
||||
try testing.expect(nodes[2].type == .text);
|
||||
try testing.expectEqualStrings("</form>", nodes[2].text.?.content);
|
||||
}
|
||||
|
||||
test "parse csrf_token sozinho" {
|
||||
const allocator = testing.allocator;
|
||||
const template = "{% csrf_token %}";
|
||||
const nodes = try parser.parse(allocator, template);
|
||||
defer {
|
||||
for (nodes) |node| node.deinit(allocator);
|
||||
allocator.free(nodes);
|
||||
}
|
||||
|
||||
try testing.expectEqual(@as(usize, 1), nodes.len);
|
||||
try testing.expect(nodes[0].type == .csrf_token);
|
||||
}
|
||||
|
||||
test "parse lorem padrão" {
|
||||
const allocator = testing.allocator;
|
||||
const template = "{% lorem %}";
|
||||
const nodes = try parser.parse(allocator, template);
|
||||
defer {
|
||||
for (nodes) |node| node.deinit(allocator);
|
||||
allocator.free(nodes);
|
||||
}
|
||||
|
||||
try testing.expectEqual(@as(usize, 1), nodes.len);
|
||||
try testing.expect(nodes[0].type == .lorem);
|
||||
const l = nodes[0].lorem.?;
|
||||
try testing.expect(l.count == null);
|
||||
try testing.expect(l.method == null);
|
||||
try testing.expect(l.format == null);
|
||||
}
|
||||
|
||||
test "parse lorem com argumentos" {
|
||||
const allocator = testing.allocator;
|
||||
const template = "{% lorem 5 p html %}";
|
||||
const nodes = try parser.parse(allocator, template);
|
||||
defer {
|
||||
for (nodes) |node| node.deinit(allocator);
|
||||
allocator.free(nodes);
|
||||
}
|
||||
|
||||
try testing.expectEqual(@as(usize, 1), nodes.len);
|
||||
try testing.expect(nodes[0].type == .lorem);
|
||||
const l = nodes[0].lorem.?;
|
||||
try testing.expectEqualStrings("5", l.count.?);
|
||||
try testing.expectEqualStrings("p", l.method.?);
|
||||
try testing.expectEqualStrings("html", l.format.?);
|
||||
}
|
||||
|
|
|
|||
35
todo.md
35
todo.md
|
|
@ -3,7 +3,7 @@
|
|||
- [x] autoescape
|
||||
- [x] block
|
||||
- [x] comment
|
||||
- [ ] csrf_token
|
||||
- [x] csrf_token
|
||||
- [x] cycle
|
||||
- [ ] debug
|
||||
- [x] extends
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
- [x] ifchanged
|
||||
- [x] include
|
||||
- [x] load
|
||||
- [ ] lorem
|
||||
- [x] lorem
|
||||
- [x] now
|
||||
- [ ] partial
|
||||
- [ ] partialdef
|
||||
|
|
@ -101,4 +101,33 @@ ___
|
|||
- [x] cycle — alternar valores em loop
|
||||
- [x] firstof — fallback de variáveis
|
||||
- [x] load — para custom tags/filters (futuro)
|
||||
- [ ] csrf_token — quando tiver web
|
||||
- [x] csrf_token — quando tiver web
|
||||
|
||||
---
|
||||
|
||||
## To do
|
||||
|
||||
1 - Finalizar o parser — completar as tags que faltam da lista:
|
||||
- [ ] debug
|
||||
- [x] lorem
|
||||
- [ ] partial / partialdef
|
||||
- [ ] querystring
|
||||
- [ ] regroup
|
||||
- [ ] resetcycle
|
||||
- [ ] templatetag
|
||||
- [ ] widthratio
|
||||
|
||||
2 - projetar o Context com calma:
|
||||
- Estrutura hierárquica (escopos aninhados para with, for, etc.)
|
||||
- Suporte a variáveis, listas, structs (models)
|
||||
- Acesso por ponto (obj.atributo, lista.0, etc.)
|
||||
- Fallback silencioso ou erro (como no Django)
|
||||
|
||||
3 - Renderer — com:
|
||||
- Resolução de variáveis
|
||||
- Aplicação de filtros
|
||||
- Herança com block.super
|
||||
- Loops com forloop
|
||||
- Tudo testado
|
||||
|
||||
4 -Filtros
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue