コード例 #1
0
ファイル: index.go プロジェクト: nota-ja/gobb
func Index(w http.ResponseWriter, request *http.Request) {
	current_user := utils.GetCurrentUser(request)
	boards, err := models.GetBoardsUnread(current_user)

	if err != nil {
		fmt.Printf("[error] Could not get boards (%s)\n", err.Error())
	}

	user_count, _ := models.GetUserCount()
	latest_user, _ := models.GetLatestUser()
	total_posts, _ := models.GetPostCount()

	utils.RenderTemplate(w, request, "index.html", map[string]interface{}{
		"boards":       boards,
		"user_count":   user_count,
		"online_users": models.GetOnlineUsers(),
		"latest_user":  latest_user,
		"total_posts":  total_posts,
	}, map[string]interface{}{
		"IsUnread": func(join *models.JoinBoardView) bool {
			latest_post := join.Board.GetLatestPost()

			if current_user != nil && !current_user.LastUnreadAll.Time.Before(latest_post.Op.LatestReply) {
				return false
			}

			return !join.ViewedOn.Valid || join.ViewedOn.Time.Before(latest_post.Op.LatestReply)
		},
	})
}
コード例 #2
0
ファイル: admin_users.go プロジェクト: nota-ja/gobb
func AdminUsers(w http.ResponseWriter, r *http.Request) {
	current_user := utils.GetCurrentUser(r)
	if current_user == nil || !current_user.IsAdmin() {
		http.NotFound(w, r)
		return
	}

	err := ""
	success := false

	starts_with := r.FormValue("starts_with")
	last_seen := r.FormValue("last_seen")

	db := models.GetDbSession()
	var users []*models.User
	if len(starts_with) == 1 {
		db.Select(&users, "SELECT * FROM users WHERE username LIKE $1", starts_with+"%")
	} else if last_seen == "1" {
		db.Select(&users, "SELECT * FROM users ORDER BY last_seen DESC")
	} else {
		db.Select(&users, "SELECT * FROM users ORDER BY id DESC")
	}

	utils.RenderTemplate(w, r, "admin_users.html", map[string]interface{}{
		"error":   err,
		"success": success,
		"users":   users,
	}, nil)
}
コード例 #3
0
ファイル: new_thread.go プロジェクト: ChimeraCoder/gobb
func NewThread(w http.ResponseWriter, r *http.Request) {
	db := models.GetDbSession()
	board_id_str := mux.Vars(r)["id"]
	board_id, _ := strconv.Atoi(board_id_str)
	err, board := models.GetBoard(board_id)

	if err != nil {
		http.NotFound(w, r)
		return
	}

	current_user := utils.GetCurrentUser(r)
	if current_user == nil {
		http.NotFound(w, r)
		return
	}

	if r.Method == "POST" {
		title := r.FormValue("title")
		content := r.FormValue("content")

		post := models.NewPost(current_user, board, title, content)
		post.LatestReply = time.Now()
		db.Insert(post)

		http.Redirect(w, r, fmt.Sprintf("/board/%d/%d", board.Id, post.Id), http.StatusFound)
		return
	}

	utils.RenderTemplate(w, r, "new_thread.html", map[string]interface{}{
		"board": board,
	})
}
コード例 #4
0
ファイル: index.go プロジェクト: ChimeraCoder/gobb
func Index(w http.ResponseWriter, request *http.Request) {
	db := models.GetDbSession()
	var boards []models.Board
	_, err := db.Select(&boards, "SELECT * FROM boards")
	if err != nil {
		fmt.Printf("[error] Could not get boards (%s)\n", err.Error())
	}

	utils.RenderTemplate(w, request, "index.html", map[string]interface{}{
		"boards": boards,
	})
}
コード例 #5
0
ファイル: login.go プロジェクト: ChimeraCoder/gobb
func Login(w http.ResponseWriter, r *http.Request) {
	if utils.GetCurrentUser(r) != nil {
		http.Redirect(w, r, "/", http.StatusFound)
		return
	}

	if r.Method == "POST" {
		username := r.FormValue("username")
		password := r.FormValue("password")

		var error string
		err, _ := models.AuthenticateUser(username, password)
		if err != nil {
			error = "Invalid username or password"
		}

		if error != "" {
			utils.RenderTemplate(w, r, "login.html", map[string]interface{}{
				"error": error,
			})
			return
		}

		session, _ := utils.Store.Get(r, "sirsid")
		session.Values["username"] = username
		session.Values["password"] = password
		fmt.Println("[notice] Auth success!")

		err = session.Save(r, w)
		if err != nil {
			fmt.Printf("[error] Could not save session (%s)\n", err.Error())
		}

		http.Redirect(w, r, "/", http.StatusFound)
		return
	}

	utils.RenderTemplate(w, r, "login.html", nil)
}
コード例 #6
0
ファイル: thread.go プロジェクト: ChimeraCoder/gobb
func Thread(w http.ResponseWriter, r *http.Request) {
	page_id_str := r.FormValue("page")
	page_id, err := strconv.Atoi(page_id_str)
	if err != nil {
		page_id = 0
	}

	board_id_str := mux.Vars(r)["board_id"]
	board_id, _ := strconv.Atoi(board_id_str)
	err, board := models.GetBoard(board_id)

	post_id_str := mux.Vars(r)["post_id"]
	post_id, _ := strconv.Atoi(post_id_str)
	err, op, posts := models.GetThread(post_id, page_id)

	if r.Method == "POST" {
		db := models.GetDbSession()
		title := r.FormValue("title")
		content := r.FormValue("content")

		current_user := utils.GetCurrentUser(r)
		if current_user == nil {
			http.NotFound(w, r)
			return
		}

		post := models.NewPost(current_user, board, title, content)
		post.ParentId = sql.NullInt64{int64(post_id), true}
		op.LatestReply = time.Now()
		db.Insert(post)
		db.Update(op)

		err, op, posts = models.GetThread(post_id, page_id)
	}

	if err != nil {
		http.NotFound(w, r)
		return
	}

	num_pages := op.GetPagesInThread()

	utils.RenderTemplate(w, r, "thread.html", map[string]interface{}{
		"board":     board,
		"op":        op,
		"posts":     posts,
		"prev_page": (page_id != 0),
		"next_page": (page_id < num_pages),
		"page_id":   page_id,
	})
}
コード例 #7
0
ファイル: register.go プロジェクト: ChimeraCoder/gobb
func Register(w http.ResponseWriter, r *http.Request) {
	if utils.GetCurrentUser(r) != nil {
		http.Redirect(w, r, "/", http.StatusFound)
		return
	}

	if r.Method == "POST" {
		username := r.FormValue("username")
		password := r.FormValue("password")
		confirm := r.FormValue("password2")

		var error string
		if password != confirm {
			error = "Passwords don't match"
		}

		if error != "" {
			utils.RenderTemplate(w, r, "register.html", map[string]interface{}{
				"error": error,
			})
			return
		}

		// We're good, let's make it
		db_map := models.GetDbSession()
		user := models.NewUser(username, password)
		err := db_map.Insert(user)

		if err != nil {
			fmt.Printf("[error] Could not insert user (%s)\n", err.Error())
		} else {
			http.Redirect(w, r, "/login", http.StatusFound)
			return
		}
	}

	utils.RenderTemplate(w, r, "register.html", nil)
}
コード例 #8
0
ファイル: actions.go プロジェクト: s2607/gobb
func ActionMoveThread(w http.ResponseWriter, r *http.Request) {
	current_user := utils.GetCurrentUser(r)
	if current_user == nil || !current_user.CanModerate() {
		http.NotFound(w, r)
		return
	}

	thread_id_str := r.FormValue("post_id")
	thread_id, err := strconv.Atoi(thread_id_str)
	board_id_str := r.FormValue("to")
	board_id, err := strconv.Atoi(board_id_str)

	op, err := models.GetPost(thread_id)
	//	boards, _ := models.GetBoardsfor(current_user.GroupId)
	boards, _ := models.GetBoards()

	if op == nil || err != nil {
		http.NotFound(w, r)
		return
	}

	if board_id_str != "" {
		db := models.GetDbSession()
		new_board, _ := models.GetBoard(board_id)
		if new_board == nil {
			http.NotFound(w, r)
			return
		}

		_, err := db.Exec("UPDATE posts SET board_id=$1 WHERE parent_id=$2", new_board.Id, op.Id)
		op.BoardId = new_board.Id
		db.Update(op)
		if err != nil {
			http.NotFound(w, r)
			fmt.Printf("Error moving post: %s\n", err.Error())
			return
		}
		http.Redirect(w, r, fmt.Sprintf("/board/%d/%d", op.BoardId, op.Id), http.StatusFound)
	}

	board, err := models.GetBoard(int(op.BoardId))

	utils.RenderTemplate(w, r, "action_move_thread.html", map[string]interface{}{
		"board":  board,
		"thread": op,
		"boards": boards,
	}, nil)
}
コード例 #9
0
ファイル: board.go プロジェクト: nota-ja/gobb
func Board(w http.ResponseWriter, r *http.Request) {
	db := models.GetDbSession()

	page_id_str := r.FormValue("page")
	page_id, err := strconv.Atoi(page_id_str)
	if err != nil {
		page_id = 0
	}

	board_id_str := mux.Vars(r)["id"]
	board_id, _ := strconv.Atoi(board_id_str)
	obj, err := db.Get(&models.Board{}, board_id)
	if err != nil || obj == nil {
		http.NotFound(w, r)
		return
	}
	board := obj.(*models.Board)

	if err != nil {
		http.NotFound(w, r)
		return
	}

	current_user := utils.GetCurrentUser(r)
	threads, err := board.GetThreads(page_id, current_user)
	if err != nil {
		fmt.Printf("[error] Could not get posts (%s)\n", err.Error())
	}

	num_pages := board.GetPagesInBoard()

	utils.RenderTemplate(w, r, "board.html", map[string]interface{}{
		"board":     board,
		"threads":   threads,
		"page_id":   page_id,
		"prev_page": (page_id != 0),
		"next_page": (page_id < num_pages),
	}, map[string]interface{}{
		"IsUnread": func(join *models.JoinThreadView) bool {
			if current_user != nil && !current_user.LastUnreadAll.Time.Before(join.LatestReply) {
				return false
			}
			return !join.ViewedOn.Valid || join.ViewedOn.Time.Before(join.LatestReply)
		},
	})
}
コード例 #10
0
ファイル: user.go プロジェクト: nota-ja/gobb
func User(w http.ResponseWriter, r *http.Request) {
	db := models.GetDbSession()

	user_id_str := mux.Vars(r)["id"]
	user_id, err := strconv.Atoi(user_id_str)

	if err != nil {
		http.NotFound(w, r)
		return
	}

	user, err := db.Get(&models.User{}, user_id)
	if err != nil {
		http.NotFound(w, r)
		return
	}

	utils.RenderTemplate(w, r, "user.html", map[string]interface{}{
		"user": user,
	}, nil)
}
コード例 #11
0
ファイル: post_editor.go プロジェクト: nota-ja/gobb
func renderPostEditor(
	w http.ResponseWriter,
	r *http.Request,
	board *models.Board,
	post *models.Post,
	err error) {

	utils.RenderTemplate(w, r, "post_editor.html", map[string]interface{}{
		"board": board,
		"post":  post,
		"error": err,
	}, map[string]interface{}{
		"ShowTitleField": func() bool {
			if post == nil {
				return true
			}

			return !post.ParentId.Valid
		},
	})
}
コード例 #12
0
ファイル: board.go プロジェクト: ChimeraCoder/gobb
func Board(w http.ResponseWriter, r *http.Request) {
	db := models.GetDbSession()

	board_id_str := mux.Vars(r)["id"]
	board_id, _ := strconv.Atoi(board_id_str)
	board, err := db.Get(models.Board{}, board_id)

	if err != nil {
		http.NotFound(w, r)
		return
	}

	var threads []*models.Post
	_, err = db.Select(&threads, "SELECT * FROM posts WHERE board_id=$1 AND parent_id IS NULL ORDER BY latest_reply DESC", board_id)
	if err != nil {
		fmt.Printf("[error] Could not get posts (%s)\n", err.Error())
	}

	utils.RenderTemplate(w, r, "board.html", map[string]interface{}{
		"board":   board,
		"threads": threads,
	})
}
コード例 #13
0
ファイル: user_settings.go プロジェクト: ChimeraCoder/gobb
func UserSettings(w http.ResponseWriter, r *http.Request) {
	user_id_str := mux.Vars(r)["id"]
	user_id, _ := strconv.Atoi(user_id_str)

	current_user := utils.GetCurrentUser(r)

	if int64(user_id) != current_user.Id {
		http.NotFound(w, r)
		return
	}

	success := false
	if r.Method == "POST" {
		db := models.GetDbSession()
		current_user.Avatar = r.FormValue("avatar_url")
		db.Update(current_user)
		success = true
	}

	utils.RenderTemplate(w, r, "user_settings.html", map[string]interface{}{
		"success": success,
	})
}
コード例 #14
0
ファイル: admin.go プロジェクト: nota-ja/gobb
func Admin(w http.ResponseWriter, r *http.Request) {
	current_user := utils.GetCurrentUser(r)
	if current_user == nil || !current_user.IsAdmin() {
		http.NotFound(w, r)
		return
	}

	var err error
	success := false
	stylesheet, _ := models.GetStringSetting("theme_stylesheet")
	favicon, _ := models.GetStringSetting("favicon_url")
	current_template, _ := models.GetStringSetting("template")

	if r.Method == "POST" {
		stylesheet = r.FormValue("theme_stylesheet")
		favicon = r.FormValue("favicon_url")
		current_template = r.FormValue("template")
		models.SetStringSetting("theme_stylesheet", stylesheet)
		models.SetStringSetting("favicon_url", favicon)
		models.SetStringSetting("template", current_template)
		success = true
	}

	utils.RenderTemplate(w, r, "admin.html", map[string]interface{}{
		"error":            err,
		"success":          success,
		"theme_stylesheet": stylesheet,
		"favicon_url":      favicon,
		"current_template": current_template,
		"templates":        utils.ListTemplates(),
	}, map[string]interface{}{
		"IsCurrentTemplate": func(name string) bool {
			return name == current_template
		},
	})
}
コード例 #15
0
ファイル: admin_boards.go プロジェクト: s2607/gobb
func AdminBoards(w http.ResponseWriter, r *http.Request) {
	current_user := utils.GetCurrentUser(r)
	if current_user == nil || !current_user.IsAdmin() {
		http.NotFound(w, r)
		return
	}

	db := models.GetDbSession()
	// Creating a board
	if r.Method == "POST" && r.FormValue("create_board") != "" {
		name := r.FormValue("title")
		desc := r.FormValue("description")
		form_order := r.FormValue("order")
		var order int

		if form_order != "" {
			if len(form_order) == 0 {
				order = 1
			} else {
				order, _ = strconv.Atoi(form_order)
			}
		} else {
			order = 1
		}

		board := models.NewBoard(name, desc, order)

		db.Insert(board)
	}

	// Update the boards
	if r.Method == "POST" && r.FormValue("update_boards") != "" {
		err := r.ParseForm()

		// loop through the post data, entries correspond via index in the map
		for i := 0; i < len(r.Form["board_id"]); i++ {
			// basically repeat the process for inserting a board
			form_id, _ := strconv.Atoi(r.Form["board_id"][i])
			id := int64(form_id)
			name := r.Form["name"][i]
			desc := r.Form["description"][i]
			form_order := r.Form["order"][i]
			groupidst := r.Form["groupid"][i]
			var order int
			var groupid int64
			if form_order != "" {
				if len(form_order) == 0 {
					order = 1
				} else {
					order, _ = strconv.Atoi(form_order)
				}
			} else {
				order = 1
			}
			if len(groupidst) < 1 {
				groupid = 0
			} else {
				groupid, _ = strconv.ParseInt(groupidst, 10, 64)
			}
			board := models.UpdateBoard(name, desc, order, id, groupid)

			db.Update(board)
		}

		if err != nil {
			http.NotFound(w, r)
			return
		}
	}

	// Delete a board
	if id := r.FormValue("delete"); id != "" {
		obj, _ := db.Get(&models.Board{}, id)

		if obj == nil {
			http.NotFound(w, r)
			return
		}

		board := obj.(*models.Board)
		board.Delete()
	}

	boards, _ := models.GetBoards()

	utils.RenderTemplate(w, r, "admin_boards.html", map[string]interface{}{
		"boards": boards,
	}, nil)
}
コード例 #16
0
ファイル: admin.go プロジェクト: ChimeraCoder/gobb
func Admin(w http.ResponseWriter, request *http.Request) {
	utils.RenderTemplate(w, request, "admin.html", nil)
}
コード例 #17
0
ファイル: admin_users.go プロジェクト: nota-ja/gobb
func AdminUser(w http.ResponseWriter, r *http.Request) {
	current_user := utils.GetCurrentUser(r)
	if current_user == nil || !current_user.IsAdmin() {
		http.NotFound(w, r)
		return
	}

	id_str := mux.Vars(r)["id"]
	id, _ := strconv.Atoi(id_str)

	user, err := models.GetUser(id)

	if err != nil || user == nil {
		http.NotFound(w, r)
		return
	}

	var form_error string
	success := false
	if r.Method == "POST" {
		db := models.GetDbSession()
		user.Username = r.FormValue("username")
		user.Avatar = r.FormValue("avatar_url")
		user.UserTitle = r.FormValue("user_title")
		user.StylesheetUrl = sql.NullString{
			Valid:  true,
			String: r.FormValue("stylesheet_url"),
		}
		if r.FormValue("signature") == "" {
			user.Signature = sql.NullString{
				Valid:  false,
				String: r.FormValue("signature"),
			}
		} else {
			user.Signature = sql.NullString{
				Valid:  true,
				String: r.FormValue("signature"),
			}
		}

		// Change hiding settings
		user.HideOnline = false
		if r.FormValue("hide_online") == "1" {
			user.HideOnline = true
		}

		// Update the username?
		if len(user.Username) < 3 {
			form_error = "Username must at least 3 characters"
		}

		// Update password?
		new_pass := r.FormValue("password_new")
		new_pass2 := r.FormValue("password_new2")
		if len(new_pass) > 0 {
			if len(new_pass) < 5 {
				form_error = "Password must be greater than 4 characters"
			} else if new_pass != new_pass2 {
				form_error = "Passwords didn't match"
			} else {
				user.SetPassword(new_pass)
			}
		}

		group_id, _ := strconv.Atoi(r.FormValue("group_id"))
		user.GroupId = int64(group_id)

		if form_error == "" {
			db.Update(user)
			success = true
		}
	}

	utils.RenderTemplate(w, r, "admin_user.html", map[string]interface{}{
		"error":   form_error,
		"success": success,
		"user":    user,
	}, nil)
}
コード例 #18
0
ファイル: user_settings.go プロジェクト: nota-ja/gobb
func UserSettings(w http.ResponseWriter, r *http.Request) {
	enable_signatures, _ := config.Config.GetBool("gobb", "enable_signatures")

	user_id_str := mux.Vars(r)["id"]
	user_id, _ := strconv.Atoi(user_id_str)

	current_user := utils.GetCurrentUser(r)

	if current_user == nil || int64(user_id) != current_user.Id {
		http.NotFound(w, r)
		return
	}

	success := false
	var form_error string
	if r.Method == "POST" {
		db := models.GetDbSession()
		current_user.Avatar = r.FormValue("avatar_url")
		current_user.UserTitle = r.FormValue("user_title")
		current_user.StylesheetUrl = sql.NullString{
			Valid:  true,
			String: r.FormValue("stylesheet_url"),
		}
		if r.FormValue("signature") == "" {
			current_user.Signature = sql.NullString{
				Valid:  false,
				String: r.FormValue("signature"),
			}
		} else {
			current_user.Signature = sql.NullString{
				Valid:  true,
				String: r.FormValue("signature"),
			}
		}

		// Change hiding settings
		current_user.HideOnline = false
		if r.FormValue("hide_online") == "1" {
			current_user.HideOnline = true
		}

		// Update password?
		old_pass := r.FormValue("password_old")
		new_pass := r.FormValue("password_new")
		new_pass2 := r.FormValue("password_new2")
		if old_pass != "" {
			err, user := models.AuthenticateUser(current_user.Username, old_pass)
			if user == nil || err != nil {
				form_error = "Invalid password"
			} else if len(new_pass) < 5 {
				form_error = "Password must be greater than 4 characters"
			} else if new_pass != new_pass2 {
				form_error = "Passwords didn't match"
			} else {
				current_user.SetPassword(new_pass)
				session, _ := utils.GetCookieStore(r).Get(r, "sirsid")
				session.Values["password"] = new_pass
				session.Save(r, w)
			}
		}

		if form_error == "" {
			db.Update(current_user)
			success = true
		}
	}

	stylesheet := ""
	if current_user.StylesheetUrl.Valid {
		stylesheet = current_user.StylesheetUrl.String
	}
	signature := ""
	if current_user.Signature.Valid {
		signature = current_user.Signature.String
	}

	utils.RenderTemplate(w, r, "user_settings.html", map[string]interface{}{
		"error":             form_error,
		"success":           success,
		"user_stylesheet":   stylesheet,
		"user_signature":    signature,
		"enable_signatures": enable_signatures,
	}, nil)
}
コード例 #19
0
ファイル: register.go プロジェクト: nmbook/gobb
func Register(w http.ResponseWriter, r *http.Request) {
	if utils.GetCurrentUser(r) != nil {
		http.Redirect(w, r, "/", http.StatusFound)
		return
	}

	if r.Method == "POST" {
		username := r.FormValue("username")
		password := r.FormValue("password")
		confirm := r.FormValue("password2")

		var error string
		if password != confirm {
			error = "Passwords don't match"
		}

		// See if a user with this name already exists
		db := models.GetDbSession()
		count, err := db.SelectInt("SELECT COUNT(*) FROM users WHERE username=$1", username)
		if count > 0 || err != nil {
			error = "This username is already taken."
		}

        if len(username) < 3 {
            error = "Username must be greater than 3 characters."
        }

		if error != "" {
			utils.RenderTemplate(w, r, "register.html", map[string]interface{}{
				"error": error,
			}, nil)
			return
		}

		// We're good, let's make it
		user := models.NewUser(username, password)
		err = db.Insert(user)

		if err != nil {
			fmt.Printf("[error] Could not insert user (%s)\n", err.Error())
			return;
		}

		// Adminify the first user
		id, err := db.SelectInt("SELECT lastval()")
		if err == nil && id == 1 {
			user.GroupId = 2
			count, err = db.Update(user)

			if err != nil {
				fmt.Printf("[error] Could not adminify user (%s)\n", err.Error())
				return;
			}
		}

		http.Redirect(w, r, "/login", http.StatusFound)
		return
	}

	utils.RenderTemplate(w, r, "register.html", nil, nil)
}
コード例 #20
0
ファイル: thread.go プロジェクト: nmbook/gobb
func Thread(w http.ResponseWriter, r *http.Request) {
	page_id_str := r.FormValue("page")
	page_id, err := strconv.Atoi(page_id_str)
	if err != nil {
		page_id = 0
	}

	board_id_str := mux.Vars(r)["board_id"]
	board_id, _ := strconv.Atoi(board_id_str)
	board, err := models.GetBoard(board_id)

	post_id_str := mux.Vars(r)["post_id"]
	post_id, _ := strconv.Atoi(post_id_str)
	err, op, posts := models.GetThread(post_id, page_id)

	var posting_error error

	current_user := utils.GetCurrentUser(r)
	if r.Method == "POST" {
		db := models.GetDbSession()
		title := r.FormValue("title")
		content := r.FormValue("content")

		if current_user == nil {
			http.NotFound(w, r)
			return
		}

		if op.Locked && !current_user.CanModerate() {
			http.NotFound(w, r)
			return
		}

		post := models.NewPost(current_user, board, title, content)
		post.ParentId = sql.NullInt64{int64(post_id), true}
		op.LatestReply = time.Now()

		posting_error = post.Validate()

		if posting_error == nil {
			db.Insert(post)
			db.Update(op)

			if page := post.GetPageInThread(); page != page_id {
				http.Redirect(w, r, fmt.Sprintf("/board/%d/%d?page=%d#post_%d", post.BoardId, op.Id, page, post.Id), http.StatusFound)
			}

			err, op, posts = models.GetThread(post_id, page_id)
		}
	}

	if err != nil {
		http.NotFound(w, r)
		fmt.Printf("[error] Something went wrong in posts (%s)\n", err.Error())
		return
	}

	num_pages := op.GetPagesInThread()

	if page_id > num_pages {
		http.NotFound(w, r)
		return
	}

	var previous_text string
	if posting_error != nil {
		previous_text = r.FormValue("content")
	}

	// Mark the thread as read
	if current_user != nil {
		models.AddView(current_user, op)
	}

	utils.RenderTemplate(w, r, "thread.html", map[string]interface{}{
		"board":         board,
		"op":            op,
		"posts":         posts,
		"first_page":    (page_id > 0),
		"prev_page":     (page_id > 1),
		"next_page":     (page_id < num_pages-1),
		"last_page":     (page_id < num_pages),
		"page_id":       page_id,
		"posting_error": posting_error,
		"previous_text": previous_text,
	}, map[string]interface{}{

		"CurrentUserCanModerateThread": func(thread *models.Post) bool {
			current_user := utils.GetCurrentUser(r)
			if current_user == nil {
				return false
			}

			return (current_user.CanModerate() && thread.ParentId.Valid == false)
		},

		"CurrentUserCanDeletePost": func(thread *models.Post) bool {
			current_user := utils.GetCurrentUser(r)
			if current_user == nil {
				return false
			}

			return (current_user.Id == thread.AuthorId) || current_user.CanModerate()
		},

		"CurrentUserCanEditPost": func(post *models.Post) bool {
			current_user := utils.GetCurrentUser(r)
			if current_user == nil {
				return false
			}

			return (current_user.Id == post.AuthorId || current_user.CanModerate())
		},

		"CurrentUserCanModerate": func() bool {
			current_user := utils.GetCurrentUser(r)
			if current_user == nil {
				return false
			}

			return current_user.CanModerate()
		},

		"SignaturesEnabled": func() bool {
			enable_signatures, _ := config.Config.GetBool("gobb", "enable_signatures")
			return enable_signatures
		},

		"ShowReplyBox": func(post *models.Post) bool {
			current_user := utils.GetCurrentUser(r)
			if current_user != nil && (!post.Locked || current_user.CanModerate()) {
				return true
			}
			return false
		},
	})
}