### xvcl Quick Start Example Source: https://github.com/dip-proto/xvcl/blob/main/README.md Demonstrates a basic xvcl usage by defining a constant and using it within a VCL subroutine. The example shows an `.xvcl` input file and its transpiled `.vcl` output. ```vcl #const MESSAGE = "Hello from xvcl!" sub vcl_recv { set req.http.X-Message = "{{MESSAGE}}"; } ``` ```bash # If installed xvcl hello.xvcl -o hello.vcl # Or run without installing using uvx uvx xvcl hello.xvcl -o hello.vcl ``` ```vcl sub vcl_recv { set req.http.X-Message = "Hello from xvcl!"; } ``` -------------------------------- ### xvcl Real-World Example: Backend Configuration Source: https://github.com/dip-proto/xvcl/blob/main/README.md Illustrates how xvcl simplifies backend configuration by using constants and for loops. The 'without xvcl' example shows repetitive manual setup, while the 'with xvcl' example demonstrates a concise and maintainable approach. ```vcl backend web1 { .host = "web1.example.com"; .port = "80"; } backend web2 { .host = "web2.example.com"; .port = "80"; } backend web3 { .host = "web3.example.com"; .port = "80"; } sub vcl_recv { if (req.http.Host == "web1.example.com") { set req.backend = web1; } if (req.http.Host == "web2.example.com") { set req.backend = web2; } if (req.http.Host == "web3.example.com") { set req.backend = web3; } } ``` ```vcl #const BACKENDS = ["web1", "web2", "web3"] #for backend in BACKENDS backend {{backend}} { .host = "{{backend}}.example.com"; .port = "80"; } #endfor sub vcl_recv { #for backend in BACKENDS if (req.http.Host == "{{backend}}.example.com") { set req.backend = {{backend}}; } #endfor } ``` -------------------------------- ### Install xvcl using uv Source: https://github.com/dip-proto/xvcl/blob/main/docs/index.html Shows how to install xvcl using 'uv', a fast Python package installer and dependency manager. This method is recommended for its speed and efficiency. ```bash uv pip install xvcl ``` -------------------------------- ### Run xvcl without installation using uvx Source: https://github.com/dip-proto/xvcl/blob/main/docs/index.html Demonstrates how to execute xvcl directly using 'uvx' without a prior installation. This is useful for quick testing or running xvcl in environments where installation is not desired. ```bash uvx xvcl input.xvcl -o output.vcl ``` -------------------------------- ### Install xvcl from source Source: https://github.com/dip-proto/xvcl/blob/main/docs/index.html Provides instructions for cloning the xvcl repository from GitHub and installing it locally using pip. This method is suitable for developers who want to work with the latest code or contribute to the project. ```bash git clone https://github.com/dip-proto/xvcl.git cd xvcl pip install -e . ``` -------------------------------- ### CI/CD Integration for xvcl and Falco (GitHub Actions) Source: https://github.com/dip-proto/xvcl/blob/main/README.md A GitHub Actions workflow file example for automating the compilation of xvcl files and linting/testing with Falco on every push or pull request. It includes steps for setting up the environment, installing tools, and running the commands. ```yaml # .github/workflows/vcl.yml name: VCL CI on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Install uv uses: astral-sh/setup-uv@v2 - name: Install Falco run: | wget https://github.com/ysugimoto/falco/releases/latest/download/falco_linux_amd64 chmod +x falco_linux_amd4 sudo mv falco_linux_amd64 /usr/local/bin/falco - name: Compile xvcl run: | uvx xvcl main.xvcl -o main.vcl - name: Lint VCL run: falco lint main.vcl - name: Test VCL run: falco test main.vcl ``` -------------------------------- ### Makefile Integration for xvcl and Falco Source: https://github.com/dip-proto/xvcl/blob/main/README.md A Makefile example demonstrating how to integrate xvcl compilation and Falco commands into build, lint, and test targets. It uses pattern rules for compiling multiple xvcl files. ```makefile # Makefile .PHONY: build lint test clean XVCL = xvcl SOURCES = $(wildcard *.xvcl) OUTPUTS = $(SOURCES:.xvcl=.vcl) build: $(OUTPUTS) %.vcl: %.xvcl $(XVCL) $< -o $@ -I ./includes lint: build falco lint *.vcl test: build falco test *.vcl clean: rm -f $(OUTPUTS) ``` -------------------------------- ### xvcl Include Directive Example Source: https://github.com/dip-proto/xvcl/blob/main/README.md Illustrates the use of the #include directive in xvcl to incorporate content from other files. This example shows how source map comments are generated. ```vcl // BEGIN INCLUDE: includes/backends.xvcl backend F_web1 { ... } // END INCLUDE: includes/backends.xvcl ``` -------------------------------- ### Install xvcl using pip Source: https://github.com/dip-proto/xvcl/blob/main/docs/index.html Provides the command to install the xvcl package using pip, a standard Python package installer. This is a common method for adding xvcl to your development environment. ```bash pip install xvcl ``` -------------------------------- ### xvcl Macro and Function Commenting Source: https://github.com/dip-proto/xvcl/blob/main/README.md Shows examples of how to comment macros and functions in xvcl code. Good commenting explains the purpose, parameters, and return values, making the code easier to understand. ```vcl // Normalizes a hostname by removing www prefix and converting to lowercase #inline normalize_host(host) std.tolower(regsub(host, "^www\.", "")) #endinline // Parses User-Agent and returns (browser, os) tuple #def parse_user_agent(ua STRING) -> (STRING, STRING) // ... #enddef ``` -------------------------------- ### xvcl Version Control Strategy Source: https://github.com/dip-proto/xvcl/blob/main/README.md Discusses two approaches to version control for xvcl projects: versioning both source and output VCL files, or versioning only source files and regenerating VCL on deployment. Includes corresponding `.gitignore` examples. ```gitignore # Include both in git *.xvcl *.vcl # But gitignore generated files in CI # (if you regenerate on deploy) # *.vcl # Version control xvcl source only *.xvcl # Ignore generated VCL *.vcl ``` -------------------------------- ### Template Expressions for Dynamic Code Generation in xvcl Source: https://github.com/dip-proto/xvcl/blob/main/docs/index.html Illustrates using Python-like template expressions within loops to dynamically generate code. This example checks request ports and assigns backends accordingly. ```xvcl #for i in range(10) if (req.http.X-Port == "{{8000 + i}}") { set req.backend = app{{i}}; } #endfor ``` -------------------------------- ### xvcl Error Context Example Source: https://github.com/dip-proto/xvcl/blob/main/README.md Illustrates how xvcl provides context for errors, showing surrounding lines of code to help pinpoint the source of the issue. This example shows an invalid #for syntax error. ```vcl Error at main.xvcl:15: Invalid #for syntax: #for in range(10) Context: 13: sub vcl_recv { 14: // Generate backends → 15: #for in range(10) 16: backend web{{i}} { ... } 17: #endfor 18: } ``` -------------------------------- ### Generate Multi-Region Backends VCL (Output Example) Source: https://github.com/dip-proto/xvcl/blob/main/docs/index.html The resulting VCL code generated by xvcl for multi-region backends. Each backend configuration is created based on the list of regions defined in the xvcl source. ```vcl backend origin_us_east { .host = "us_east.api.example.com"; .port = "443"; .ssl = true; .connect_timeout = 5s; } backend origin_us_west { .host = "us_west.api.example.com"; .port = "443"; .ssl = true; .connect_timeout = 5s; } // ... eu_central, ap_southeast ``` -------------------------------- ### Generate VCL with For Loops (Output Example) Source: https://github.com/dip-proto/xvcl/blob/main/docs/index.html This is the generated VCL output from an xvcl source file that uses a for loop to define multiple backend configurations. It shows the resulting standard VCL code. ```vcl backend web0 { .host = "web0.example.com"; .port = "80"; } backend web1 { .host = "web1.example.com"; .port = "80"; } // ... web2, web3, web4 ``` -------------------------------- ### Define and Use VCL Functions Source: https://github.com/dip-proto/xvcl/blob/main/README.md Demonstrates how to define reusable functions with parameters and return values in VCL. Functions are compiled into VCL subroutines, supporting type safety and multiple return values. This example shows a simple addition function. ```vcl #def add(a INTEGER, b INTEGER) -> INTEGER declare local var.sum INTEGER; set var.sum = a + b; return var.sum; #enddef sub vcl_recv { declare local var.result INTEGER; set var.result = add(5, 10); set req.http.X-Sum = var.result; } ``` -------------------------------- ### Compile xvcl files using the command line interface Source: https://context7.com/dip-proto/xvcl/llms.txt The `xvcl` command-line tool compiles `.xvcl` source files into standard VCL output. It supports various options for include paths, debugging, and source map generation. The `uvx` command can be used to run `xvcl` without installation. ```bash # Basic compilation xvcl input.xvcl -o output.vcl # With include paths for modular projects xvcl main.xvcl -o main.vcl -I ./includes -I ./shared # Debug mode to trace expansion xvcl main.xvcl -o main.vcl --debug # Add source map comments for debugging xvcl main.xvcl -o main.vcl --source-maps # Run without installing using uvx uvx xvcl input.xvcl -o output.vcl ``` -------------------------------- ### Reusable string manipulation pattern Source: https://github.com/dip-proto/xvcl/blob/main/xvcl-quick-reference.md A VCL pattern showing reusable string manipulation logic defined using an inline macro (`#inline`). This example normalizes hostnames. ```vcl #inline normalize_host(host) std.tolower(regsub(host, "^www\.", "")) #endinline set req.http.X-Clean-Host = normalize_host(req.http.Host); ``` -------------------------------- ### Falco Test Case for VCL Source: https://github.com/dip-proto/xvcl/blob/main/README.md An example of a Falco test file (`.test.vcl`) written to test the functionality of compiled VCL code. It includes a test suite and a specific test case to verify backend routing. ```vcl // @suite: Backend routing tests // @test: Should route to correct backend sub test_backend_routing { set req.http.Host = "web1.example.com"; call vcl_recv; assert.equal(req.backend, "web1"); } ``` -------------------------------- ### xvcl Descriptive Constant Naming Source: https://github.com/dip-proto/xvcl/blob/main/README.md Emphasizes the importance of using descriptive names for constants in xvcl code to enhance readability and maintainability. Contrasts good examples with less informative ones. ```text // Good #const CACHE_TTL_SECONDS = 3600 #const API_BACKEND_HOST = "api.example.com" // Bad #const X = 3600 #const B = "api.example.com" ``` -------------------------------- ### VCL Function with Tuple Return (Multiple Values) Source: https://github.com/dip-proto/xvcl/blob/main/README.md Demonstrates defining a VCL function that returns multiple values using tuple syntax. This example parses a User-Agent string to extract browser and operating system information. ```vcl #def parse_user_agent(ua STRING) -> (STRING, STRING) declare local var.browser STRING; declare local var.os STRING; if (ua ~ "Chrome") { set var.browser = "chrome"; } else if (ua ~ "Firefox") { set var.browser = "firefox"; } else { set var.browser = "other"; } if (ua ~ "Windows") { set var.os = "windows"; } else if (ua ~ "Mac") { set var.os = "macos"; } else { set var.os = "other"; } return var.browser, var.os; #enddef sub vcl_recv { declare local var.browser STRING; declare local var.os STRING; set var.browser, var.os = parse_user_agent(req.http.User-Agent); set req.http.X-Browser = var.browser; set req.http.X-OS = var.os; } ``` -------------------------------- ### Generate Lookup Tables in VCL Source: https://context7.com/dip-proto/xvcl/llms.txt This snippet demonstrates how to generate lookup tables in VCL using xvcl's for loop and expression capabilities. It includes examples for creating a byte-to-hex mapping and HTTP status code descriptions. These tables are useful for dynamic data mapping within VCL. ```vcl // Generate a byte-to-hex lookup table (256 entries) table byte_to_hex STRING { #for i in range(256) "{{i}}": "{{format(i, '02x')}}"{{ ", " if i < 255 else ""}} #endfor } // Generate HTTP status code descriptions #const STATUS_CODES = [200, 201, 301, 302, 400, 401, 403, 404, 500, 502, 503] #const STATUS_MESSAGES = ["OK", "Created", "Moved Permanently", "Found", "Bad Request", "Unauthorized", "Forbidden", "Not Found", "Internal Server Error", "Bad Gateway", "Service Unavailable"] table status_messages STRING { #for i in range(len(STATUS_CODES)) "{{STATUS_CODES[i]}}": "{{STATUS_MESSAGES[i]}}"{{ ", " if i < len(STATUS_CODES) - 1 else ""}} #endfor } sub vcl_deliver { set resp.http.X-Status-Message = table.lookup(status_messages, resp.status); } ``` -------------------------------- ### Create and Compile a Simple xvcl File Source: https://github.com/dip-proto/xvcl/blob/main/docs/index.html Shows how to create a basic xvcl file 'hello.xvcl' with constants and a loop, then compile it into standard VCL using the 'xvcl' command. It also includes validation with 'falco lint'. ```xvcl #const SERVICE_NAME STRING = "My Awesome Service" sub vcl_recv { set req.http.X-Service = "{{SERVICE_NAME}}"; #for i in range(3) if (req.http.X-Backend-ID == "{{i}}") { set req.backend = backend{{i}}; } #endfor } #for i in range(3) backend backend{{i}} { .host = "backend{{i}}.example.com"; .port = "80"; } #endfor ``` ```bash xvcl hello.xvcl -o hello.vcl falco lint hello.vcl ``` -------------------------------- ### Recommended Workflow with Falco Source: https://github.com/dip-proto/xvcl/blob/main/README.md Outlines the recommended workflow for using xvcl with Falco, involving writing xvcl code, compiling it, and then using Falco for linting, testing, and simulation. ```bash # 1. Write your xvcl source vim main.xvcl # 2. Compile with xvcl xvcl main.xvcl -o main.vcl # 3. Lint with Falco falco lint main.vcl # 4. Test with Falco falco test main.vcl # 5. Simulate with Falco falco simulate main.vcl ``` -------------------------------- ### xvcl Workflow: Compile, Validate, Test, Deploy Source: https://github.com/dip-proto/xvcl/blob/main/xvcl-quick-reference.md This bash script outlines the typical workflow for developing and deploying xvcl code. It covers writing the xvcl file, compiling it to VCL, validating the VCL with Falco, testing it, and finally deploying it. ```bash # 1. Write xvcl file vim main.xvcl # 2. Compile xvcl main.xvcl -o main.vcl # 3. Validate with Falco falco lint main.vcl # 4. Test falco test main.vcl # 5. Deploy # (upload main.vcl to Fastly) ``` -------------------------------- ### Compile xvcl files using the command line Source: https://github.com/dip-proto/xvcl/blob/main/xvcl-quick-reference.md This snippet shows how to compile xvcl files to VCL using the xvcl command-line tool. It includes options for specifying include paths and enabling debug mode. ```bash # Compile an xvcl file xvcl input.xvcl -o output.vcl # With include paths xvcl input.xvcl -o output.vcl -I ./includes # Debug mode xvcl input.xvcl --debug ``` -------------------------------- ### Environment Configuration with Conditional Logic in xvcl Source: https://github.com/dip-proto/xvcl/blob/main/docs/index.html Illustrates environment configuration using xvcl constants and conditional compilation. It shows how to set headers based on the 'DEBUG' and 'ENV' constants, demonstrating conditional inclusion and exclusion of VCL statements. ```xvcl #const ENV STRING = "production" #const DEBUG BOOL = false sub vcl_recv { #if DEBUG set req.http.X-Debug = "enabled"; set req.http.X-Timestamp = now; #endif set req.http.X-Environment = "{{ENV}}"; #if ENV == "production" unset req.http.X-Internal-Header; #endif } ``` ```vcl sub vcl_recv { set req.http.X-Environment = "production"; unset req.http.X-Internal-Header; } ``` -------------------------------- ### Backend generation from a list pattern Source: https://github.com/dip-proto/xvcl/blob/main/xvcl-quick-reference.md A common VCL pattern demonstrating how to dynamically generate backend definitions from a list of names using a `#for` loop. ```vcl #const BACKENDS = ["web1", "web2", "web3"] #for backend in BACKENDS backend F_{{backend}} { .host = "{{backend}}.example.com"; .port = "443"; } #endfor ``` -------------------------------- ### xvcl Macro Definition and Usage Source: https://github.com/dip-proto/xvcl/blob/main/README.md Defines and uses an inline macro in xvcl. The example shows how xvcl automatically adds parentheses for correct operator precedence during expansion. ```vcl #inline double(x) x + x #endinline set var.result = double(1 + 2); ``` -------------------------------- ### Generate Backends with For Loops and List Iteration in xvcl Source: https://github.com/dip-proto/xvcl/blob/main/docs/index.html Shows how to use a for loop to iterate over a list of strings (regions) and dynamically generate backend configurations for each region. This is useful for multi-region deployments. ```xvcl #const REGIONS = ["us_east", "us_west", "eu_central", "ap_southeast"] #for region in REGIONS backend origin_{{region}} { .host = "{{region}}.api.example.com"; .port = "443"; .ssl = true; .connect_timeout = 5s; } #endfor ``` -------------------------------- ### Generate VCL Code with Enumerate For Loops Source: https://github.com/dip-proto/xvcl/blob/main/README.md Use the `enumerate` function within for loops to iterate over a list while also getting the index of each item. This is helpful for creating indexed variables or headers. ```vcl #const REGIONS = ["us-east", "us-west", "eu-west"] #for idx, region in enumerate(REGIONS) set req.http.X-Region-{{idx}} = "{{region}}"; #endfor ``` -------------------------------- ### xvcl Constants Placement Source: https://github.com/dip-proto/xvcl/blob/main/README.md Illustrates the best practice of placing constants at the beginning of an xvcl file for easy identification and management. This includes using `#const` for defining constants and `#for` loops for iteration. ```vcl // Good: Constants first, easy to find #const MAX_BACKENDS = 10 #const PRODUCTION = True #for i in range(MAX_BACKENDS) // ... use constant #endfor ``` -------------------------------- ### xvcl Development Workflow Source: https://github.com/dip-proto/xvcl/blob/main/docs/index.html Outlines the typical development workflow for xvcl, which involves writing xvcl code, compiling it to VCL, validating with Falco, testing, and finally deploying to Fastly. ```bash # 1. Compile xvcl to VCL xvcl main.xvcl -o main.vcl -I ./includes # 2. Lint the generated VCL falco lint -vv main.vcl # 3. Run tests falco test main.vcl # 4. Simulate locally falco simulate main.vcl # 5. Deploy to Fastly (using Fastly CLI) fastly vcl custom update --version=latest --name=main --content=main.vcl ``` -------------------------------- ### String Formatting with VCL Template Expressions Source: https://github.com/dip-proto/xvcl/blob/main/README.md Illustrates string formatting using VCL template expressions, combining constants to construct dynamic backend names. ```vcl #const REGION = "us-east" #const INDEX = 1 set req.backend = F_backend_{{REGION}}_{{INDEX}}; ``` -------------------------------- ### Include other VCL files Source: https://github.com/dip-proto/xvcl/blob/main/xvcl-quick-reference.md Explains how to include content from other VCL files using the `#include` directive. Supports both double-quote and angle-bracket path syntaxes. ```vcl #include "path/to/file.xvcl" #include // Angle bracket syntax // Examples: #include "includes/backends.xvcl" #include "shared/security.xvcl" ``` -------------------------------- ### Environment-specific configuration pattern Source: https://github.com/dip-proto/xvcl/blob/main/xvcl-quick-reference.md Illustrates a common VCL pattern for setting configuration values based on an environment flag (e.g., PRODUCTION) using `#if` directives. ```vcl #const PRODUCTION = True #if PRODUCTION #const CACHE_TTL = 3600 #const BACKEND_HOST = "prod.example.com" #else #const CACHE_TTL = 60 #const BACKEND_HOST = "dev.example.com" #endif ``` -------------------------------- ### xvcl Include Structure Source: https://github.com/dip-proto/xvcl/blob/main/README.md Illustrates a recommended directory structure for organizing xvcl code using includes. This promotes modularity and maintainability by separating different concerns into distinct files. ```text vcl/ ├── main.xvcl # Main entry point ├── config.xvcl # Constants and configuration ├── includes/ │ ├── backends.xvcl │ ├── security.xvcl │ ├── routing.xvcl │ └── caching.xvcl ``` -------------------------------- ### Fade In Sections on Scroll (JavaScript) Source: https://github.com/dip-proto/xvcl/blob/main/docs/index.html Uses the Intersection Observer API to fade in specific sections of the page as they become visible in the viewport. It targets elements with classes like 'feature-card', 'example', etc., and adds a 'fade-in' class when they intersect the viewport. ```javascript const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('fade-in'); } }); }, observerOptions); document.querySelectorAll('.feature-card, .example, .doc-card, .why-card').forEach(el => { observer.observe(el); }); ``` -------------------------------- ### Implement for loops in VCL Source: https://github.com/dip-proto/xvcl/blob/main/xvcl-quick-reference.md Illustrates the use of `#for` loops for iteration in VCL. Supports simple iteration, tuple unpacking, and using `enumerate` for index-based iteration. ```vcl #for variable in iterable #for var1, var2 in iterable // tuple unpacking // Examples: #for i in range(5) backend web{{i}} { ... } #endfor #for name, port in [("web", 80), ("api", 8080)] backend {{name}} { .port = "{{port}}"; } #endfor #for idx, name in enumerate(NAMES) set req.http.X-{{idx}} = "{{name}}"; #endfor ``` -------------------------------- ### Define functions in VCL Source: https://github.com/dip-proto/xvcl/blob/main/xvcl-quick-reference.md Shows how to define functions in VCL using `#def` and `#enddef`. Supports functions with single or multiple return values (tuples) and type annotations. ```vcl // Single return value #def function_name(param1 TYPE, param2 TYPE) -> RETURN_TYPE // function body return value; #enddef // Multiple return values (tuple) #def function_name(param TYPE) -> (TYPE1, TYPE2) // function body return value1, value2; #enddef // Examples: #def normalize(path STRING) -> STRING declare local var.result STRING; set var.result = std.tolower(path); return var.result; #enddef #def parse(input STRING) -> (STRING, STRING) return "part1", "part2"; #enddef // Usage: set var.clean = normalize("/PATH"); set var.a, var.b = parse("input"); ``` -------------------------------- ### Configure Multi-Region Backends in VCL Source: https://context7.com/dip-proto/xvcl/llms.txt This snippet illustrates a pattern for generating backend configurations across multiple regions and environments using xvcl. It defines backends dynamically based on a list of regions and includes logic to route requests to the appropriate backend based on a request header or a default region. ```vcl #const REGIONS = ["us-east", "us-west", "eu-west", "ap-south"] #const DEFAULT_REGION = "us-east" // Generate backends for each region #for region in REGIONS backend F_origin_{{region}} { .host = "origin-{{region}}.example.com"; .port = "443"; .ssl = true; .connect_timeout = 5s; .first_byte_timeout = 30s; } #endfor sub vcl_recv { declare local var.region STRING; if (req.http.X-Region) { set var.region = req.http.X-Region; } else { set var.region = "{{DEFAULT_REGION}}"; } // Route to appropriate backend #for region in REGIONS if (var.region == "{{region}}") { set req.backend = F_origin_{{region}}; } #endfor } ``` -------------------------------- ### Define Constants and Use For Loops in xvcl Source: https://github.com/dip-proto/xvcl/blob/main/docs/index.html Demonstrates defining an integer constant and using a for loop to generate multiple backend configurations based on that constant. This reduces repetitive code for similar backend definitions. ```xvcl #const MAX_BACKENDS INTEGER = 5 #for i in range(MAX_BACKENDS) backend web{{i}} { .host = "web{{i}}.example.com"; .port = "80"; } #endfor ``` -------------------------------- ### Incremental Testing Workflow Source: https://github.com/dip-proto/xvcl/blob/main/README.md Demonstrates a workflow for incrementally developing and testing xvcl code. It involves writing code, compiling, checking the output, and linting. ```bash # Write a bit vim main.xvcl # Compile xvcl main.xvcl # Check output cat main.vcl # Lint falco lint main.vcl # Repeat ``` -------------------------------- ### Include Other xvcl Files Source: https://github.com/dip-proto/xvcl/blob/main/docs/index.html Demonstrates how to include other xvcl files using the `#include` directive. This promotes modularity and organization of VCL configurations, with built-in checks for circular dependencies. ```xvcl #include "backends.xvcl" #include "functions.xvcl" #include "security.xvcl" ``` -------------------------------- ### Initialize Syntax Highlighting (JavaScript) Source: https://github.com/dip-proto/xvcl/blob/main/docs/index.html Initializes syntax highlighting for code blocks on the page using the highlight.js library. It selects all `pre code` elements and applies highlighting when the DOM is fully loaded. ```javascript document.addEventListener('DOMContentLoaded', (event) => { document.querySelectorAll('pre code').forEach((block) => { hljs.highlightElement(block); }); }); ``` -------------------------------- ### Declare local variables in VCL Source: https://github.com/dip-proto/xvcl/blob/main/xvcl-quick-reference.md Shows how to declare local variables using the `#let` directive in VCL. This is a shorthand for declaring and initializing a variable. ```vcl #let name TYPE = expression; // Example: #let timestamp STRING = std.time(now, now); // Expands to: // declare local var.timestamp STRING; // set var.timestamp = std.time(now, now); ``` -------------------------------- ### xvcl Source Maps for Debugging Source: https://github.com/dip-proto/xvcl/blob/main/README.md Explains how to use the `--source-maps` flag during xvcl compilation to generate source maps, which aids in debugging the compiled VCL code by linking it back to the original xvcl source. ```bash # Development: easier debugging xvcl main.xvcl -o main.vcl --source-maps ``` -------------------------------- ### xvcl Source File Extension Source: https://github.com/dip-proto/xvcl/blob/main/README.md Demonstrates the recommended file extension `.xvcl` for source files to distinguish them from compiled VCL files. This improves clarity and organization. ```text ✓ main.xvcl → main.vcl ✗ main.vcl → main.vcl.processed ``` -------------------------------- ### xvcl Compiler Command-Line Options Source: https://github.com/dip-proto/xvcl/blob/main/README.md Lists and describes common command-line options for the xvcl compiler, including specifying input/output files, include paths, and enabling debug or source map generation. ```bash # Basic compilation xvcl main.xvcl -o main.vcl # With include paths xvcl main.xvcl -o main.vcl \ -I ./includes \ -I ./shared # Debug mode (see expansion traces) xvcl main.xvcl -o main.vcl --debug # With source maps (track generated code origin) xvcl main.xvcl -o main.vcl --source-maps ``` -------------------------------- ### Define inline macros in VCL Source: https://github.com/dip-proto/xvcl/blob/main/xvcl-quick-reference.md Demonstrates the creation of inline macros using `#inline` and `#endinline` in VCL. These macros are simple text substitutions and are useful for reusable code snippets. ```vcl #inline macro_name(param1, param2, ...) expression #endinline // Examples: #inline add_prefix(s) "prefix-" + s #endinline #inline cache_key(url, host) digest.hash_md5(url + "|" + host) #endinline // Usage: set req.http.X-Key = cache_key(req.url, req.http.Host); ``` -------------------------------- ### xvcl Macros vs. Functions Source: https://github.com/dip-proto/xvcl/blob/main/README.md Provides guidance on when to use macros versus functions in xvcl. Macros are recommended for simple expressions, while functions are better suited for complex logic. ```vcl // Good: Simple expression = macro #inline cache_key(url, host) digest.hash_md5(url + "|" + host) #endinline // Good: Complex logic = function #def should_cache(url STRING, method STRING) -> BOOL declare local var.result BOOL; if (method != "GET" && method != "HEAD") { set var.result = false; } else if (url ~ "^/api/") { set var.result = false; } else { set var.result = true; } return var.result; #enddef ``` -------------------------------- ### xvcl Compiler Basic Command-Line Usage Source: https://github.com/dip-proto/xvcl/blob/main/README.md Provides the basic command-line syntax for compiling xvcl input files to VCL output files. It specifies the required input file and the optional output file flag. ```bash xvcl input.xvcl -o output.vcl ``` -------------------------------- ### Compile xvcl to VCL Source: https://github.com/dip-proto/xvcl/blob/main/README.md Compiles an xvcl source file into a VCL configuration file. The output can be directed to standard output or a specified file using the -o flag. ```bash xvcl main.xvcl -o main.vcl ``` -------------------------------- ### Use conditional statements in VCL Source: https://github.com/dip-proto/xvcl/blob/main/xvcl-quick-reference.md Demonstrates VCL conditional logic using `#if`, `#else`, and `#endif` directives. Allows for code execution based on specified conditions. ```vcl #if condition // code when true #else // code when false (optional) #endif // Examples: #if PRODUCTION set req.http.X-Env = "prod"; #else set req.http.X-Env = "dev"; #endif ``` -------------------------------- ### Use template expressions in VCL Source: https://github.com/dip-proto/xvcl/blob/main/xvcl-quick-reference.md Shows how to use template expressions `{{expression}}` for embedding dynamic values within VCL code. Supports arithmetic operations, function calls like `hex()`, and ternary expressions. ```vcl {{expression}} // Examples: set req.http.X-Port = "{{PORT}}"; backend F_{{REGION}}_{{ENV}} { ... } set req.http.X-Value = "{{PORT * 2}}"; set req.http.X-Hex = "{{hex(PORT)}}"; // Ternary expressions: "{{value if condition else other}}" ``` -------------------------------- ### Define and Use Reusable Functions in xvcl Source: https://github.com/dip-proto/xvcl/blob/main/docs/index.html Demonstrates how to define a reusable function 'cache_key' in xvcl that generates a cache key based on URL and User-ID. It also shows how this function is called within the 'vcl_hash' subroutine in both the xvcl source and the generated VCL. ```xvcl #def cache_key(url STRING, user STRING) -> STRING declare local var.key STRING; set var.key = url + ":" + user; return std.tolower(var.key); #enddef sub vcl_hash { declare local var.key STRING; set var.key = cache_key(req.url, req.http.User-ID); set req.hash += var.key; } ``` ```vcl sub vcl_hash { declare local var.key STRING; set req.http.X-Func-cache_key-url = req.url; set req.http.X-Func-cache_key-user = req.http.User-ID; call cache_key; set var.key = req.http.X-Func-cache_key-Return; set req.hash += var.key; } // Function subroutine generated at end of file sub cache_key { // Parameter unpacking, function body... } ``` -------------------------------- ### Generate VCL Code with Nested For Loops Source: https://github.com/dip-proto/xvcl/blob/main/README.md Demonstrates the use of nested for loops to generate VCL code based on combinations of items from multiple lists. This is useful for creating configurations that span multiple dimensions, like regions and environments. ```vcl #const REGIONS = ["us", "eu"] #const ENVS = ["prod", "staging"] #for region in REGIONS #for env in ENVS backend {{region}}_{{env}} { .host = "{{env}}.{{region}}.example.com"; .port = "443"; } #endfor #endfor ``` -------------------------------- ### Conditional Compilation with If/Else in xvcl Source: https://github.com/dip-proto/xvcl/blob/main/docs/index.html Illustrates using conditional compilation directives (#if, #else, #endif) to include different code blocks based on a predefined constant (PRODUCTION). This allows for environment-specific configurations. ```xvcl #if PRODUCTION set req.http.X-Debug = "false"; #else set req.http.X-Debug = "true"; #endif ``` -------------------------------- ### Compile xvcl to VCL Source: https://github.com/dip-proto/xvcl/blob/main/README.md Compiles an xvcl source file into a VCL file. The `-o` flag specifies the output file name. This is the fundamental command for using xvcl. ```bash xvcl main.xvcl xvcl main.xvcl -o main.vcl ``` -------------------------------- ### Declare and Initialize Local Variables with #let in VCL Source: https://github.com/dip-proto/xvcl/blob/main/README.md The #let directive in VCL allows for the declaration and initialization of local variables in a single step. This is a shorthand for declaring a variable and then setting its value, reducing boilerplate code and clearly indicating the initialization point. It is useful for defining temporary variables within subroutines. ```vcl sub vcl_recv { #let timestamp STRING = std.time(now, now); #let cache_key STRING = req.url.path + req.http.Host; set req.http.X-Timestamp = var.timestamp; set req.hash = var.cache_key; } ``` -------------------------------- ### VCL File Includes - #include Directive for Modularity Source: https://context7.com/dip-proto/xvcl/llms.txt Organizes VCL code into reusable components using the #include directive. Supports relative paths and include-once semantics for modularity. ```vcl // main.xvcl #include "includes/constants.xvcl" #include "includes/backends.xvcl" #include "includes/security.xvcl" sub vcl_recv { call security_checks; call routing_logic; } // includes/constants.xvcl #const MAX_AGE = 3600 #const ORIGIN_HOST = "origin.example.com" // includes/backends.xvcl #const BACKENDS = ["web1", "web2", "web3"] #for backend in BACKENDS backend F_{{backend}} { .host = "{{backend}}.{{ORIGIN_HOST}}"; .port = "443"; } #endfor ``` -------------------------------- ### Configure Multi-region Backends in VCL Source: https://github.com/dip-proto/xvcl/blob/main/README.md This VCL snippet configures multiple backend servers for different regions and routes requests to the appropriate backend based on a client-provided header or a default region. It defines backend configurations and uses conditional logic within `vcl_recv` to select the correct backend. ```vcl #const REGIONS = ["us-east", "us-west", "eu-west", "ap-south"] #const DEFAULT_REGION = "us-east" #for region in REGIONS backend F_origin_{{region}} { .host = "origin-{{region}}.example.com"; .port = "443"; .ssl = true; .connect_timeout = 5s; .first_byte_timeout = 30s; .between_bytes_timeout = 10s; } #endfor sub vcl_recv { declare local var.region STRING; // Detect region from client IP or header if (req.http.X-Region) { set var.region = req.http.X-Region; } else { set var.region = "{{DEFAULT_REGION}}"; } // Route to appropriate backend #for region in REGIONS if (var.region == "{{region}}") { set req.backend = F_origin_{{region}}; } #endfor } ``` -------------------------------- ### Use VCL Constants in Templates Source: https://github.com/dip-proto/xvcl/blob/main/README.md Demonstrates how to define and use constants within VCL templates. These constants are substituted during preprocessing, allowing for a single source of truth for configuration values. ```vcl #const TTL = 300 #const BACKEND_HOST = "api.example.com" backend F_api { .host = "{{BACKEND_HOST}}"; .port = "443"; } sub vcl_fetch { set beresp.ttl = {{TTL}}s; } ``` -------------------------------- ### xvcl For Loop Syntax Source: https://github.com/dip-proto/xvcl/blob/main/README.md Demonstrates the syntax for a #for loop in xvcl, including the requirement for a corresponding #endfor directive to close the loop block. ```vcl #for i in range(10) backend web{{i}} { ... } #endfor ``` -------------------------------- ### Define constants in VCL Source: https://github.com/dip-proto/xvcl/blob/main/xvcl-quick-reference.md Demonstrates how to define constants in VCL, including explicit type declarations and type inference from values. Supported types are INTEGER, STRING, FLOAT, and BOOL. ```vcl #const NAME TYPE = value #const NAME = value // Type inferred from value // Examples: #const PORT INTEGER = 8080 #const HOST STRING = "example.com" #const ENABLED BOOL = True #const VERSION FLOAT = 1.5 // Type inference: #const BACKENDS = ["web1", "web2"] // List #const TTL = 300 // Integer ``` -------------------------------- ### xvcl Debug Mode Output Source: https://github.com/dip-proto/xvcl/blob/main/README.md Demonstrates the output when running xvcl in debug mode. This provides detailed information about each compilation pass, including constants, macros, includes, and directives processing. ```bash $ xvcl example.xvcl --debug [DEBUG] Processing file: example.xvcl [DEBUG] Pass 1: Extracting constants [DEBUG] Defined constant: MAX_AGE = 3600 [DEBUG] Pass 2: Processing includes [DEBUG] Pass 3: Extracting inline macros [DEBUG] Defined macro: add_prefix(s) [DEBUG] Pass 4: Extracting functions [DEBUG] Pass 5: Processing directives and generating code [DEBUG] Processing #for at line 10 [DEBUG] Loop iterating 3 times [DEBUG] Iteration 0: backend = web1 [DEBUG] Iteration 1: backend = web2 [DEBUG] Iteration 2: backend = web3 [DEBUG] Pass 6: Generating function subroutines ✓ Compiled example.xvcl -> example.vcl Constants: 1 Macros: 1 (add_prefix) Functions: 0 ``` -------------------------------- ### VCL Inline Macros - #inline Directive for Substitution Source: https://context7.com/dip-proto/xvcl/llms.txt Provides zero-overhead text substitution at compile time using the #inline directive. Ideal for common expressions and functions without runtime cost. ```vcl // Define macros for common operations #inline add_prefix(s) "prefix-" + s #endinline #inline normalize_host(host) std.tolower(regsub(host, "^www\.", "")) #endinline #inline cache_key(url, host) digest.hash_md5(url + "|" + host) #endinline sub vcl_recv { // Use macros like function calls set req.http.X-Modified = add_prefix("test"); set req.http.X-Normalized = normalize_host(req.http.Host); set req.hash = cache_key(req.url, req.http.Host); } // Expands to: // set req.http.X-Modified = "prefix-" + "test"; // set req.http.X-Normalized = std.tolower(regsub(req.http.Host, "^www\.", "")); // set req.hash = digest.hash_md5(req.url + "|" + req.http.Host); ``` -------------------------------- ### VCL Variables - #let Directive for Declarations Source: https://context7.com/dip-proto/xvcl/llms.txt Declares and initializes VCL local variables in a single statement using the #let directive. Reduces boilerplate code for variable management. ```vcl sub vcl_recv { // Single statement declaration and initialization #let timestamp STRING = std.time(now, now); #let cache_key STRING = req.url.path + req.http.Host; #let request_id STRING = randomstr(16, "0123456789abcdef"); set req.http.X-Timestamp = var.timestamp; set req.hash = var.cache_key; set req.http.X-Request-ID = var.request_id; } // Expands to: // declare local var.timestamp STRING; // set var.timestamp = std.time(now, now); // declare local var.cache_key STRING; // set var.cache_key = req.url.path + req.http.Host; // ... ``` -------------------------------- ### Include External VCL Files with #include Source: https://github.com/dip-proto/xvcl/blob/main/README.md The #include directive allows developers to split large VCL files into smaller, modular, and reusable components. Files can be included from paths relative to the current file or specified include paths. This feature supports include-once semantics, cycle detection, and shared constants, promoting better organization and collaboration. ```vcl #include "includes/backends.xvcl" #include "includes/security.xvcl" #include "includes/routing.xvcl" sub vcl_recv { call security_checks; call routing_logic; } ``` ```vcl #const BACKENDS = ["web1", "web2", "web3"] #for backend in BACKENDS backend F_{{backend}} { .host = "{{backend}}.example.com"; .port = "443"; } #endfor ``` -------------------------------- ### Inline Macros for Text Substitution in xvcl Source: https://github.com/dip-proto/xvcl/blob/main/docs/index.html Shows the usage of inline macros (`#inline`) for simple, zero-overhead text substitution. The `is_mobile` macro takes a user agent string and performs a regular expression substitution. ```xvcl #inline is_mobile(ua) regsuball(ua, "(?i)mobile|android", "") #endinline ``` -------------------------------- ### Define and Use Functions in xvcl Source: https://github.com/dip-proto/xvcl/blob/main/docs/index.html Demonstrates defining a reusable function `normalize` that takes a string argument and returns a string. The function compiles to a VCL subroutine and is used to process request URLs. ```xvcl #def normalize(url STRING) -> STRING return std.tolower(url); #enddef set req.url = normalize(req.url); ``` -------------------------------- ### Complex reusable logic pattern Source: https://github.com/dip-proto/xvcl/blob/main/xvcl-quick-reference.md Demonstrates a more complex VCL pattern using a defined function (`#def`) to encapsulate reusable logic, such as determining cacheability based on URL and method. ```vcl #def should_cache(url STRING, method STRING) -> BOOL if (method != "GET" && method != "HEAD") { return false; } if (url ~ "^/api/") { return false; } return true; #enddef set var.cacheable = should_cache(req.url, req.request); ``` -------------------------------- ### Implement Feature Flags in VCL Source: https://github.com/dip-proto/xvcl/blob/main/README.md This VCL snippet demonstrates a feature flag system using constants to control the enablement of different features like new cache policies, WebP conversion, analytics, and debug headers. It uses conditional compilation (`#if`, `#else`, `#endif`) to include or exclude code blocks based on these flags. ```vcl #const ENABLE_NEW_CACHE_POLICY = True #const ENABLE_WEBP_CONVERSION = True #const ENABLE_ANALYTICS = False #const ENABLE_DEBUG_HEADERS = False sub vcl_recv { #if ENABLE_NEW_CACHE_POLICY // New cache policy with fine-grained control if (req.url.path ~ "\.(jpg|png|gif|css|js)$") { set req.http.X-Cache-Policy = "static"; } else { set req.http.X-Cache-Policy = "dynamic"; } #else // Legacy cache policy set req.http.X-Cache-Policy = "default"; #endif #if ENABLE_WEBP_CONVERSION if (req.http.Accept ~ "image/webp") { set req.http.X-Image-Format = "webp"; } #endif #if ENABLE_ANALYTICS set req.http.X-Analytics-ID = uuid.generate(); #endif } sub vcl_deliver { #if ENABLE_DEBUG_HEADERS set resp.http.X-Cache-Status = resp.http.X-Cache; set resp.http.X-Backend = req.backend; set resp.http.X-Region = req.http.X-Region; #endif } ```