vweb #

This is pre-alpha software.

Features

  • Very fast: performance of C on the web.
  • Small binary: hello world website is <100 KB.
  • Easy to deploy: just one binary file that also includes all templates. No need to install any dependencies.
  • Templates are precompiled, all errors are visible at compilation time, not at runtime.

Lots of things are broken and not implemented yet in V and vweb.

There's no documentation yet, have a look at a simple example:

https://github.com/vlang/v/tree/master/examples/vweb/vweb_example.v

There's also the V forum: https://github.com/vlang/vorum

vorum.v contains all GET and POST actions.

pub fn (app mut App) index() {
    posts := app.find_all_posts()
    $vweb.html()
}

// TODO ['/post/:id/:title']
// TODO `fn (app App) post(id int)`
pub fn (app App) post() {
    id := app.get_post_id()
    post := app.retrieve_post(id) or {
        app.redirect('/')
        return
    }
    comments := app.find_comments(id)
    show_form := true
    $vweb.html()
}

index.html is an example of the V template language:

@for post in posts
    <div class=post>
        <a class=topic href="@post.url">@post.title</a>
        <img class=comment-img>
        <span class=nr-comments>@post.nr_comments</span>
        <span class=time>@post.time</span>
    </div>
@end

$vweb.html() compiles an HTML template into V during compilation, and embeds the resulting code in current action.

That means that the template automatically has access to that action's entire environment.

Deploying vweb apps

Everything, including HTML templates, is in one binary file. That's all you need to deploy.

Constants #

const (
	methods_with_form       = [http.Method.post, .put, .patch]
	methods_without_first   = ['ost', 'ut', 'et', 'atch', 'ptions', 'elete', 'ead']
	header_server           = 'Server: VWeb\r\n'
	header_connection_close = 'Connection: close\r\n'
	headers_close           =''$2header_server$header_connection_close\r\n'
	http_404                = 'HTTP/1.1 404 Not Found\r\nContent-Type: text/plain\r\nContent-Length: 13\r\n${headers_close}404 Not Found'
	http_500                = 'HTTP/1.1 500 Internal Server Error\r\nContent-Type: text/plain\r\n${headers_close}500 Internal Server Error'
	mime_types              = {
		'.css':  'text/css; charset=utf-8'
		'.gif':  'image/gif'
		'.htm':  'text/html; charset=utf-8'
		'.html': 'text/html; charset=utf-8'
		'.jpg':  'image/jpeg'
		'.js':   'application/javascript'
		'.json': 'application/json'
		'.md':   'text/markdown; charset=utf-8'
		'.pdf':  'application/pdf'
		'.png':  'image/png'
		'.svg':  'image/svg+xml'
		'.txt':  'text/plain; charset=utf-8'
		'.wasm': 'application/wasm'
		'.xml':  'text/xml; charset=utf-8'
	}
	max_http_post_size      = 1024 * 1024
	default_port            = 8080
)

fn not_found #

fn not_found() Result

fn run #

fn run<T>(port int)

fn handle_conn(conn net.Socket) { println('handle') }

fn run_app #

fn run_app<T>(mut app T, port int)

type RawHtml #

type RawHtml = string

struct Context #

struct Context {
mut:
	content_type string = 'text/plain'
	status       string = '200 OK'
pub:
	req http.Request
pub mut:
	conn              &net.TcpConn
	static_files      map[string]string
	static_mime_types map[string]string
	form              map[string]string
	query             map[string]string
	files             map[string][]FileData
	headers           string
	done              bool
	page_gen_start    i64
	form_error        string
	chunked_transfer  bool
	max_chunk_len     int = 20
}

fn (Context) init_once #

fn (ctx Context) init_once()

declaring init_once in your App struct is optional

fn (Context) init #

fn (ctx Context) init()

declaring init in your App struct is optional

fn (Context) uninit #

fn (ctx Context) uninit()

declaring uninit in your App struct is optional

fn (Context) send_response_to_client #

fn (mut ctx Context) send_response_to_client(mimetype string, res string) bool

fn (Context) html #

fn (mut ctx Context) html(s string) Result

fn (Context) text #

fn (mut ctx Context) text(s string) Result

fn (Context) json #

fn (mut ctx Context) json(s string) Result

fn (Context) ok #

fn (mut ctx Context) ok(s string) Result

fn (Context) redirect #

fn (mut ctx Context) redirect(url string) Result

fn (Context) not_found #

fn (mut ctx Context) not_found() Result

fn (Context) enable_chunked_transfer #

fn (mut ctx Context) enable_chunked_transfer(max_chunk_len int)

fn (Context) set_content_type #

fn (mut ctx Context) set_content_type(typ string)

fn (Context) set_status #

fn (mut ctx Context) set_status(code int, desc string)

fn (Context) add_header #

fn (mut ctx Context) add_header(key string, val string)

fn (Context) get_header #

fn (ctx &Context) get_header(key string) string

fn (Context) parse_form #

fn (mut ctx Context) parse_form(s string)

fn (Context) parse_multipart_form #

fn (mut ctx Context) parse_multipart_form(s string, b string)

fn (Context) handle_static #

fn (mut ctx Context) handle_static(directory_path string) bool

fn (Context) serve_static #

fn (mut ctx Context) serve_static(url string, file_path string, mime_type string)

fn (Context) ip #

fn (ctx &Context) ip() string

fn (Context) error #

fn (mut ctx Context) error(s string)

struct Result #

struct Result {
}