Beispiel #1
0
func ArticleHandler(ctx *app.Context) {
	slug := ctx.IndexValue(0)
	var art *article.Article
	articles := getArticles(ctx)
	for _, v := range articles {
		if v.Slug() == slug {
			art = v
			break
		}
	}
	if art == nil {
		for _, v := range articles {
			for _, s := range v.AllSlugs() {
				if s == slug {
					ctx.MustRedirectReverse(true, ctx.HandlerName(), s)
					return
				}
			}
		}
		ctx.NotFound("article not found")
		return
	}
	fs := vfs.Memory()
	filename := path.Base(art.Filename)
	if filename == "" {
		filename = "article.html"
	}
	if err := vfs.WriteFile(fs, filename, art.Text, 0644); err != nil {
		panic(err)
	}
	log.Debugf("loading article %s", articleId(art))
	tmpl, err := app.LoadTemplate(ctx.App(), fs, nil, filename)
	if err != nil {
		panic(err)
	}
	var buf bytes.Buffer
	if err := tmpl.ExecuteTo(&buf, ctx, nil); err != nil {
		panic(err)
	}
	body := buf.String()
	data := map[string]interface{}{
		"Article": art,
		"Title":   art.Title(),
		"Body":    template.HTML(body),
	}
	ctx.MustExecute("article.html", data)
}
Beispiel #2
0
func UserImageHandler(ctx *app.Context) {
	if ImageHandler != nil {
		ImageHandler(ctx)
		return
	}
	id := ctx.IndexValue(0)
	format := ctx.IndexValue(1)
	if lower := strings.ToLower(format); lower != format {
		ctx.MustRedirectReverse(true, ImageHandlerName, id, lower)
		return
	}
	ctx.SetHeader("Content-Type", "image/"+format)
	httpserve.NeverExpires(ctx)
	bs := ctx.Blobstore()
	if err := bs.Serve(ctx, id, nil); err != nil {
		panic(err)
	}
}
Beispiel #3
0
// NewPager returns a new *Pager instance. Note that the
// Context must satisfy the conditions mentioned in the
// Pager type documentation. Otherwise an error will be
// returned.
func NewPager(ctx *app.Context) (*Pager, error) {
	name := ctx.HandlerName()
	if name == "" {
		return nil, errors.New("can't generate a pager from an unnamed handler")
	}
	names := ctx.Provider().ParamNames()
	if len(names) == 0 {
		return nil, errors.New("can't generate a pager from a handler with no parameters, must have a page parameter")
	}
	if names[len(names)-1] != "page" {
		return nil, fmt.Errorf("last named parameter is %q, not page", names[len(names)-1])
	}
	params := make([]interface{}, ctx.Count()-1)
	for ii := 0; ii < ctx.Count()-1; ii++ {
		params[ii] = ctx.IndexValue(ii)
	}
	return &Pager{
		Name:       name,
		Parameters: params,
		Ctx:        ctx,
	}, nil
}
Beispiel #4
0
func PackageHandler(ctx *app.Context) {
	dctx := getEnvironment(ctx)
	rel := ctx.IndexValue(0)
	if rel[len(rel)-1] == '/' {
		ctx.MustRedirectReverse(true, PackageHandlerName, rel[:len(rel)-1])
		return
	}
	pkg, err := dctx.ImportPackage(rel)
	if err != nil {
		panic(err)
	}
	var title string
	var header string
	var distinct bool
	switch {
	case pkg.IsMain():
		title = "Command " + path.Base(rel)
		header = title
	case pkg.IsEmpty():
		prefix := "Directory "
		header = prefix + path.Base(rel)
		if pkg.ImportPath() != "" {
			title = prefix + pkg.ImportPath()
		} else {
			title = header
		}
	default:
		title = "Package " + pkg.ImportPath()
		header = "Package " + pkg.Name()
		distinct = path.Base(pkg.ImportPath()) != pkg.Name()
	}
	breadcrumbs := []*breadcrumb{
		{Title: "Index", Href: ctx.MustReverse(ListHandlerName)},
	}
	if pkg.IsStd() {
		breadcrumbs = append(breadcrumbs, &breadcrumb{
			Title: "std",
			Href:  ctx.MustReverse(PackageHandlerName, "std"),
		})
	}
	for ii := 0; ii < len(rel); {
		var end int
		slash := strings.IndexByte(rel[ii:], '/')
		if slash < 0 {
			end = len(rel)
		} else {
			end = ii + slash
		}
		breadcrumbs = append(breadcrumbs, &breadcrumb{
			Title: rel[ii:end],
			Href:  ctx.MustReverse(PackageHandlerName, rel[:end]),
		})
		ii = end + 1
	}
	data := map[string]interface{}{
		"Header":      header,
		"Title":       title,
		"Breadcrumbs": breadcrumbs,
		"Package":     pkg,
		"Distinct":    distinct,
	}
	ctx.MustExecute("package.html", data)
}
Beispiel #5
0
func SourceHandler(ctx *app.Context) {
	dctx := doc.GetEnvironment(ctx.App())
	rel := ctx.IndexValue(0)
	p := dctx.FromSlash(rel)
	pDir := dctx.Dir(p)
	if pDir == "." {
		pDir = p
	} else {

	}
	dir := packageDir(dctx, pDir)
	filePath := dir
	if pDir+dctx.Separator != p && pDir != p {
		filePath = dctx.Join(dir, dctx.Base(p))
	}
	log.Debugf("Loading source from %s", filePath)
	var breadcrumbs []*breadcrumb
	for ii := 0; ii < len(rel); {
		var end int
		slash := strings.IndexByte(rel[ii:], '/')
		if slash < 0 {
			end = len(rel)
		} else {
			end = ii + slash
		}
		breadcrumbs = append(breadcrumbs, &breadcrumb{
			Title: rel[ii:end],
			Href:  ctx.MustReverse(SourceHandlerName, rel[:end]),
		})
		ii = end + 1
	}
	var tmpl string
	var title string
	var files []string
	var code template.HTML
	var lines []int
	if dctx.IsDir(filePath) {
		if rel != "" && rel[len(rel)-1] != '/' {
			ctx.MustRedirectReverse(true, SourceHandlerName, rel+"/")
			return
		}
		contents, err := dctx.ReadDir(filePath)
		if err != nil {
			panic(err)
		}
		for _, v := range contents {
			if n := v.Name(); len(n) > 0 && n[0] != '.' {
				files = append(files, n)
			}
		}
		title = "Directory " + dctx.Base(rel)
		tmpl = "dir.html"
	} else {
		f, err := dctx.OpenFile(filePath)
		if err != nil {
			ctx.NotFound("File not found")
			return
		}
		defer f.Close()
		contents, err := ioutil.ReadAll(f)
		if err != nil {
			panic(err)
		}
		contentType := http.DetectContentType(contents)
		if !strings.HasPrefix(contentType, "text") {
			ctx.Header().Set("Content-Type", contentType)
			switch contentType {
			case "image/gif", "image/png", "image/jpeg":
			default:
				ctx.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s;", dctx.Base(rel)))
			}
			ctx.Write(contents)
			return
		}
		title = "File " + dctx.Base(rel)
		var buf bytes.Buffer
		buf.WriteString("<span id=\"line-1\">")
		last := 0
		line := 1
		for ii, v := range contents {
			if v == '\n' {
				buf.WriteString(html.Escape(string(contents[last:ii])))
				lines = append(lines, line)
				last = ii
				line++
				buf.WriteString(fmt.Sprintf("</span><span id=\"line-%d\">", line))
			}
		}
		buf.Write(contents[last:])
		buf.WriteString("</span>")
		code = template.HTML(buf.String())
		tmpl = "source.html"
	}
	data := map[string]interface{}{
		"Title":       rel,
		"Header":      title,
		"Breadcrumbs": breadcrumbs,
		"Files":       files,
		"Code":        code,
		"Lines":       lines,
		"Padding":     math.Ceil(math.Log10(float64(len(lines)+1))) + 0.1,
		"Highlighter": highlighters[path.Ext(rel)],
	}
	ctx.MustExecute(tmpl, data)
}