mirror of
https://github.com/joshuadavidthomas/django-language-server.git
synced 2025-09-11 21:06:31 +00:00
wip
This commit is contained in:
parent
39862b2d63
commit
5dbffd4494
35 changed files with 121 additions and 143 deletions
|
@ -4,6 +4,7 @@ resolver = "2"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
djls = { path = "crates/djls" }
|
djls = { path = "crates/djls" }
|
||||||
|
djls-conf = { path = "crates/djls-conf" }
|
||||||
djls-project = { path = "crates/djls-project" }
|
djls-project = { path = "crates/djls-project" }
|
||||||
djls-server = { path = "crates/djls-server" }
|
djls-server = { path = "crates/djls-server" }
|
||||||
djls-templates = { path = "crates/djls-templates" }
|
djls-templates = { path = "crates/djls-templates" }
|
||||||
|
|
16
crates/djls-conf/Cargo.toml
Normal file
16
crates/djls-conf/Cargo.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "djls-conf"
|
||||||
|
version = "0.0.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
djls-templates = { workspace = true }
|
||||||
|
|
||||||
|
anyhow = { workspace = true }
|
||||||
|
serde = { workspace = true }
|
||||||
|
thiserror = { workspace = true }
|
||||||
|
|
||||||
|
config = { version = "0.15", features = ["toml"] }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
tempfile = "3.19"
|
12
crates/djls-conf/src/lib.rs
Normal file
12
crates/djls-conf/src/lib.rs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
use config::{Config, File, FileFormat, Value};
|
||||||
|
use djls_templates::TagSpecs;
|
||||||
|
use serde::Deserialize;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug, Default, Clone)]
|
||||||
|
pub struct Settings {
|
||||||
|
#[serde(default)]
|
||||||
|
pub debug: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub tagspecs: TagSpecs,
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::ast::{AstError, Span};
|
|
||||||
use crate::lexer::LexerError;
|
use crate::lexer::LexerError;
|
||||||
|
use crate::nodes::{AstError, Span};
|
||||||
use crate::parser::ParserError;
|
use crate::parser::ParserError;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
mod ast;
|
|
||||||
mod error;
|
mod error;
|
||||||
mod lexer;
|
mod lexer;
|
||||||
|
mod nodes;
|
||||||
mod parser;
|
mod parser;
|
||||||
mod tagspecs;
|
mod tagspecs;
|
||||||
mod tokens;
|
mod tokens;
|
||||||
|
|
||||||
use ast::Ast;
|
|
||||||
pub use error::{to_lsp_diagnostic, QuickFix, TemplateError};
|
pub use error::{to_lsp_diagnostic, QuickFix, TemplateError};
|
||||||
|
|
||||||
use lexer::Lexer;
|
use lexer::Lexer;
|
||||||
|
use nodes::NodeList;
|
||||||
pub use parser::{Parser, ParserError};
|
pub use parser::{Parser, ParserError};
|
||||||
|
pub use tagspecs::TagSpecs;
|
||||||
|
|
||||||
/// Parses a Django template and returns the AST and any parsing errors.
|
/// Parses a Django template and returns the AST and any parsing errors.
|
||||||
///
|
///
|
||||||
|
@ -18,7 +18,7 @@ pub use parser::{Parser, ParserError};
|
||||||
///
|
///
|
||||||
/// Returns a `Result` containing a tuple of `(Ast, Vec<ParserError>)` on success,
|
/// Returns a `Result` containing a tuple of `(Ast, Vec<ParserError>)` on success,
|
||||||
/// or a `ParserError` on failure.
|
/// or a `ParserError` on failure.
|
||||||
pub fn parse_template(source: &str) -> Result<(Ast, Vec<TemplateError>), TemplateError> {
|
pub fn parse_template(source: &str) -> Result<(NodeList, Vec<TemplateError>), TemplateError> {
|
||||||
let tokens = Lexer::new(source)
|
let tokens = Lexer::new(source)
|
||||||
.tokenize()
|
.tokenize()
|
||||||
.map_err(|e| TemplateError::Lexer(e.to_string()))?;
|
.map_err(|e| TemplateError::Lexer(e.to_string()))?;
|
||||||
|
|
|
@ -3,14 +3,14 @@ use serde::Serialize;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Serialize)]
|
#[derive(Clone, Debug, Default, Serialize)]
|
||||||
pub struct Ast {
|
pub struct NodeList {
|
||||||
nodelist: Vec<Node>,
|
nodes: Vec<Node>,
|
||||||
line_offsets: LineOffsets,
|
line_offsets: LineOffsets,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ast {
|
impl NodeList {
|
||||||
pub fn nodelist(&self) -> &Vec<Node> {
|
pub fn nodes(&self) -> &Vec<Node> {
|
||||||
&self.nodelist
|
&self.nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn line_offsets(&self) -> &LineOffsets {
|
pub fn line_offsets(&self) -> &LineOffsets {
|
||||||
|
@ -18,18 +18,11 @@ impl Ast {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_node(&mut self, node: Node) {
|
pub fn add_node(&mut self, node: Node) {
|
||||||
self.nodelist.push(node);
|
self.nodes.push(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_line_offsets(&mut self, tokens: &TokenStream) {
|
pub fn set_line_offsets(&mut self, tokens: &TokenStream) {
|
||||||
for token in tokens.tokens() {
|
self.line_offsets = LineOffsets::from_tokens(tokens)
|
||||||
if let TokenType::Newline = token.token_type() {
|
|
||||||
if let Some(start) = token.start() {
|
|
||||||
// Add offset for next line
|
|
||||||
self.line_offsets.add_line(start + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,8 +30,20 @@ impl Ast {
|
||||||
pub struct LineOffsets(pub Vec<u32>);
|
pub struct LineOffsets(pub Vec<u32>);
|
||||||
|
|
||||||
impl LineOffsets {
|
impl LineOffsets {
|
||||||
|
pub fn from_tokens(tokens: &TokenStream) -> Self {
|
||||||
|
let mut offsets = LineOffsets::default();
|
||||||
|
for token in tokens.tokens() {
|
||||||
|
if let TokenType::Newline = token.token_type() {
|
||||||
|
if let Some(start) = token.start() {
|
||||||
|
offsets.add_line(start + token.length().unwrap_or(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offsets
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_line(&mut self, offset: u32) {
|
pub fn add_line(&mut self, offset: u32) {
|
||||||
self.0.push(offset);
|
self.0.push(offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn position_to_line_col(&self, position: usize) -> (usize, usize) {
|
pub fn position_to_line_col(&self, position: usize) -> (usize, usize) {
|
||||||
|
@ -188,7 +193,7 @@ mod tests {
|
||||||
assert!(errors.is_empty());
|
assert!(errors.is_empty());
|
||||||
|
|
||||||
// Find the variable node
|
// Find the variable node
|
||||||
let nodes = nodelist.nodelist();
|
let nodes = nodelist.nodes();
|
||||||
let var_node = nodes
|
let var_node = nodes
|
||||||
.iter()
|
.iter()
|
||||||
.find(|n| matches!(n, Node::Variable { .. }))
|
.find(|n| matches!(n, Node::Variable { .. }))
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::ast::{Ast, AstError, Node, Span};
|
|
||||||
use crate::lexer::LexerError;
|
use crate::lexer::LexerError;
|
||||||
|
use crate::nodes::{AstError, Node, NodeList, Span};
|
||||||
use crate::tokens::{Token, TokenStream, TokenType};
|
use crate::tokens::{Token, TokenStream, TokenType};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
@ -18,8 +18,8 @@ impl Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(&mut self) -> Result<(Ast, Vec<ParserError>), ParserError> {
|
pub fn parse(&mut self) -> Result<(NodeList, Vec<ParserError>), ParserError> {
|
||||||
let mut ast = Ast::default();
|
let mut ast = NodeList::default();
|
||||||
ast.set_line_offsets(&self.tokens);
|
ast.set_line_offsets(&self.tokens);
|
||||||
|
|
||||||
while !self.is_at_end() {
|
while !self.is_at_end() {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Text:
|
- Text:
|
||||||
content: "<!-- HTML comment -->"
|
content: "<!-- HTML comment -->"
|
||||||
span:
|
span:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Tag:
|
- Tag:
|
||||||
name: if
|
name: if
|
||||||
bits:
|
bits:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Tag:
|
- Tag:
|
||||||
name: for
|
name: for
|
||||||
bits:
|
bits:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Tag:
|
- Tag:
|
||||||
name: if
|
name: if
|
||||||
bits:
|
bits:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Tag:
|
- Tag:
|
||||||
name: url
|
name: url
|
||||||
bits:
|
bits:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Variable:
|
- Variable:
|
||||||
var: user.name
|
var: user.name
|
||||||
filters: []
|
filters: []
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Variable:
|
- Variable:
|
||||||
var: user.name
|
var: user.name
|
||||||
filters:
|
filters:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Variable:
|
- Variable:
|
||||||
var: value
|
var: value
|
||||||
filters:
|
filters:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Text:
|
- Text:
|
||||||
content: "Welcome,"
|
content: "Welcome,"
|
||||||
span:
|
span:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Tag:
|
- Tag:
|
||||||
name: for
|
name: for
|
||||||
bits:
|
bits:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Text:
|
- Text:
|
||||||
content: "<div class=\"container\">"
|
content: "<div class=\"container\">"
|
||||||
span:
|
span:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Tag:
|
- Tag:
|
||||||
name: for
|
name: for
|
||||||
bits:
|
bits:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Tag:
|
- Tag:
|
||||||
name: if
|
name: if
|
||||||
bits:
|
bits:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Text:
|
- Text:
|
||||||
content: "<div>"
|
content: "<div>"
|
||||||
span:
|
span:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Text:
|
- Text:
|
||||||
content: "<script>console.log('test');"
|
content: "<script>console.log('test');"
|
||||||
span:
|
span:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Text:
|
- Text:
|
||||||
content: "<style>body { color: blue;"
|
content: "<style>body { color: blue;"
|
||||||
span:
|
span:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Text:
|
- Text:
|
||||||
content: "<!DOCTYPE html>"
|
content: "<!DOCTYPE html>"
|
||||||
span:
|
span:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Text:
|
- Text:
|
||||||
content: "<!DOCTYPE html>"
|
content: "<!DOCTYPE html>"
|
||||||
span:
|
span:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Text:
|
- Text:
|
||||||
content: "<div class=\"container\">Hello</div>"
|
content: "<div class=\"container\">Hello</div>"
|
||||||
span:
|
span:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Text:
|
- Text:
|
||||||
content: "<input type=\"text\" />"
|
content: "<input type=\"text\" />"
|
||||||
span:
|
span:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Text:
|
- Text:
|
||||||
content: "<script type=\"text/javascript\">"
|
content: "<script type=\"text/javascript\">"
|
||||||
span:
|
span:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Text:
|
- Text:
|
||||||
content: "<style type=\"text/css\">"
|
content: "<style type=\"text/css\">"
|
||||||
span:
|
span:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Text:
|
- Text:
|
||||||
content: hello
|
content: hello
|
||||||
span:
|
span:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Text:
|
- Text:
|
||||||
content: hello
|
content: hello
|
||||||
span:
|
span:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Text:
|
- Text:
|
||||||
content: hello
|
content: hello
|
||||||
span:
|
span:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
source: crates/djls-templates/src/parser.rs
|
source: crates/djls-templates/src/parser.rs
|
||||||
expression: nodelist
|
expression: nodelist
|
||||||
---
|
---
|
||||||
nodelist:
|
nodes:
|
||||||
- Text:
|
- Text:
|
||||||
content: hello
|
content: hello
|
||||||
span:
|
span:
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::{Path, PathBuf}; // Add PathBuf
|
use std::path::{Path, PathBuf}; // Add PathBuf
|
||||||
|
@ -226,7 +225,8 @@ fn extract_specs(
|
||||||
if !current_path.is_empty() {
|
if !current_path.is_empty() {
|
||||||
match TagSpec::deserialize(current_value.clone()) {
|
match TagSpec::deserialize(current_value.clone()) {
|
||||||
Ok(tag_spec) => {
|
Ok(tag_spec) => {
|
||||||
if let Some(tag_name) = current_path.split('.').last().filter(|s| !s.is_empty()) {
|
if let Some(tag_name) = current_path.split('.').last().filter(|s| !s.is_empty())
|
||||||
|
{
|
||||||
specs_map.insert(tag_name.to_string(), tag_spec);
|
specs_map.insert(tag_name.to_string(), tag_spec);
|
||||||
} else {
|
} else {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
|
@ -296,7 +296,7 @@ mod tests {
|
||||||
// Renamed from test_can_load_builtins
|
// Renamed from test_can_load_builtins
|
||||||
let content = r#"
|
let content = r#"
|
||||||
# Using dotted path table names under [tagspecs] base
|
# Using dotted path table names under [tagspecs] base
|
||||||
[tagspecs.django.template.defaulttags.if] // Corrected path
|
[tagspecs.django.template.defaulttags.if]
|
||||||
end = { tag = "endif" }
|
end = { tag = "endif" }
|
||||||
[tagspecs.django.template.defaulttags.block]
|
[tagspecs.django.template.defaulttags.block]
|
||||||
end = { tag = "endblock" }
|
end = { tag = "endblock" }
|
||||||
|
|
|
@ -1,104 +1,48 @@
|
||||||
[django.template.defaulttags.autoescape]
|
[tagspecs.django.template.defaulttags.autoescape]
|
||||||
args = [{ name = "setting", required = true, allowed_values = ["on", "off"] }]
|
end = { tag = "endautoescape" }
|
||||||
closing = "endautoescape"
|
|
||||||
type = "container"
|
|
||||||
|
|
||||||
[django.template.defaulttags.block]
|
[tagspecs.django.template.defaulttags.block]
|
||||||
closing = "endblock"
|
end = { tag = "endblock" }
|
||||||
type = "container"
|
|
||||||
|
|
||||||
[django.template.defaulttags.comment]
|
[tagspecs.django.template.defaulttags.comment]
|
||||||
closing = "endcomment"
|
end = { tag = "endcomment" }
|
||||||
type = "container"
|
|
||||||
|
|
||||||
[django.template.defaulttags.cycle]
|
[tagspecs.django.template.defaulttags.filter]
|
||||||
args = [
|
end = { tag = "endfilter" }
|
||||||
{ name = "cyclevars", required = true },
|
|
||||||
{ name = "variable_name", required = false, is_kwarg = true },
|
|
||||||
]
|
|
||||||
type = "single"
|
|
||||||
|
|
||||||
[django.template.defaulttags.debug]
|
[tagspecs.django.template.defaulttags.for]
|
||||||
type = "single"
|
end = { tag = "endfor" }
|
||||||
|
intermediates = [ "empty" ]
|
||||||
|
|
||||||
[django.template.defaulttags.extends]
|
[tagspecs.django.template.defaulttags.if]
|
||||||
args = [{ name = "parent_name", required = true }]
|
end = { tag = "endif" }
|
||||||
type = "inclusion"
|
intermediates = [ "elif", "else" ]
|
||||||
|
|
||||||
[django.template.defaulttags.for]
|
[tagspecs.django.template.defaulttags.ifchanged]
|
||||||
args = [
|
end = { tag = "endifchanged" }
|
||||||
{ name = "{item}", required = true },
|
intermediates = [ "else" ]
|
||||||
{ name = "in", required = true },
|
|
||||||
{ name = "{iterable}", required = true },
|
|
||||||
]
|
|
||||||
branches = ["empty"]
|
|
||||||
closing = "endfor"
|
|
||||||
type = "container"
|
|
||||||
|
|
||||||
[django.template.defaulttags.filter]
|
[tagspecs.django.template.defaulttags.spaceless]
|
||||||
args = [{ name = "filter_expr", required = true }]
|
end = { tag = "endspaceless" }
|
||||||
closing = "endfilter"
|
|
||||||
type = "container"
|
|
||||||
|
|
||||||
[django.template.defaulttags.firstof]
|
[tagspecs.django.template.defaulttags.verbatim]
|
||||||
args = [{ name = "variables", required = true }]
|
end = { tag = "endverbatim" }
|
||||||
type = "single"
|
|
||||||
|
|
||||||
[django.template.defaulttags.if]
|
[tagspecs.django.template.defaulttags.with]
|
||||||
args = [{ name = "condition", required = true }]
|
end = { tag = "endwith" }
|
||||||
branches = ["elif", "else"]
|
|
||||||
closing = "endif"
|
|
||||||
type = "container"
|
|
||||||
|
|
||||||
[django.template.defaulttags.include]
|
[tagspecs.django.templatetags.cache.cache]
|
||||||
args = [
|
end = { tag = "endcache" }
|
||||||
{ name = "template", required = true },
|
|
||||||
{ name = "with", required = false, is_kwarg = true },
|
|
||||||
{ name = "only", required = false, is_kwarg = true },
|
|
||||||
]
|
|
||||||
type = "inclusion"
|
|
||||||
|
|
||||||
[django.template.defaulttags.load]
|
[tagspecs.django.templatetags.i10n.localize]
|
||||||
args = [{ name = "library", required = true }]
|
end = { tag = "endlocalize" }
|
||||||
type = "single"
|
|
||||||
|
|
||||||
[django.template.defaulttags.now]
|
[tagspecs.django.templatetags.i18n.blocktranslate]
|
||||||
args = [{ name = "format_string", required = true }]
|
end = { tag = "endblocktranslate" }
|
||||||
type = "single"
|
intermediates = [ "plural" ]
|
||||||
|
|
||||||
[django.template.defaulttags.spaceless]
|
[tagspecs.django.templatetags.tz.localtime]
|
||||||
closing = "endspaceless"
|
end = { tag = "endlocaltime" }
|
||||||
type = "container"
|
|
||||||
|
|
||||||
[django.template.defaulttags.templatetag]
|
[tagspecs.django.templatetags.tz.timezone]
|
||||||
type = "single"
|
end = { tag = "endtimezone" }
|
||||||
|
|
||||||
[[django.template.defaulttags.templatetag.args]]
|
|
||||||
allowed_values = [
|
|
||||||
"openblock",
|
|
||||||
"closeblock",
|
|
||||||
"openvariable",
|
|
||||||
"closevariable",
|
|
||||||
"openbrace",
|
|
||||||
"closebrace",
|
|
||||||
"opencomment",
|
|
||||||
"closecomment",
|
|
||||||
]
|
|
||||||
name = "tagtype"
|
|
||||||
required = true
|
|
||||||
|
|
||||||
[django.template.defaulttags.url]
|
|
||||||
args = [
|
|
||||||
{ name = "view_name", required = true },
|
|
||||||
{ name = "asvar", required = false, is_kwarg = true },
|
|
||||||
]
|
|
||||||
type = "single"
|
|
||||||
|
|
||||||
[django.template.defaulttags.verbatim]
|
|
||||||
closing = "endverbatim"
|
|
||||||
type = "container"
|
|
||||||
|
|
||||||
[django.template.defaulttags.with]
|
|
||||||
args = [{ name = "extra_context", required = true }]
|
|
||||||
closing = "endwith"
|
|
||||||
type = "container"
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue