구인 공고 웹 사이트: 게시물 항목 읽기




GitHub: https://github.com/Sokhavuth/opine-job
데노 배치: https://khmerweb-job.deno.dev/users/post

일반적으로 프로그래밍 데이터베이스는 데이터베이스에서 데이터를 생성, 읽기, 업데이트 및 삭제하는 프로세스입니다. 우리는 이러한 네 가지 기본 프로그래밍 접근 방식을 CRUD라고 합니다.

우리는 대시보드에서 게시물을 만들 때 이미 하나의 데이터베이스 프로그래밍 접근 방식을 사용하고 있습니다. 이제 "R"접근 방식을 사용하여 MongoDB 데이터베이스에서 게시물을 읽거나 가져옵니다. 이를 위해 "users/post"경로에서 HTTP GET 메서드를 사용하여 데이터베이스에서 게시물을 읽거나 가져옵니다. "users/post"경로의 HTTP GET 메소드가 이미 정의되었으므로 이 목표를 달성하기 위해 해야 할 일은 컨트롤러 Post 클래스의 getPage 메소드에 명령문을 추가하는 것입니다.

데이터베이스에서 가져온 게시물을 템플릿 페이지 post.jsx로 보내 이 데이터를 index.jsx 페이지로 전달하여 바닥글에 표시할 여러 게시물 항목을 만듭니다.


// controllers/users/post.js

import post from "../../views/users/post.jsx";
import postdb from "../../models/post.ts";


class Post{
    async getPage(req, res){
        const config = req.mysetting();
        config.page_title = "Post Page";
        config.route = "/users/post";
        config.username = (await req.mysession.get("user")).title;
        config.type = "post";
        config.count = await postdb.count(req);
        config.items = await postdb.getPosts(req, config.dasPostAmount);

        const html = await post(config);
        res.send(html);
    }

    async createPost(req, res){
        if((await req.mysession.get("user")).role in {'Admin':1,'Editor':1,'Author':1}){
            await postdb.createPost(req);
        }

        res.redirect("/users/post");
    }
}


export default new Post();



// models/post.ts


interface PostSchema {
    _id: ObjectId;
    id: string; 
    title: string;
    content: string;
    categories: string[];
    location: string;
    payable: string;
    postdate: Date;
    closedate: string;
    userid: string;
    thumb: string;
}

class Post{
    async count(req, query={}){
        const posts = req.mydb.collection<PostSchema>("posts");
        return await posts.countDocuments(query);
    }

    async createPost(req){
        const id = crypto.randomUUID();

        let categories: string[];

        if(req.body.categories.includes(',')){
            categories = req.body.categories.split(',');
        }else{
            categories = [req.body.categories]
        }

        const new_post = {
            id: id, 
            title: req.body.title,
            content: req.body.content,
            categories: categories,
            location: req.body.location,
            payable: req.body.payable,
            postdate: new Date(),
            closedate: req.body.datetime,
            userid: (await req.mysession.get("user")).id,
            thumb: req.body.thumb,
        }

        const posts = req.mydb.collection<PostSchema>("posts")
        await posts.insertOne(new_post)
    }

    async getPosts(req, amount, query={}){
        const posts = req.mydb.collection<PostSchema>("posts");
        return await posts.find(query).sort({date:-1,_id:-1}).limit(amount).toArray();
    }
}

export default new Post();



// views/users/index.jsx

/** @jsx h */
import { h } from "../../deps.ts";
import Base from "../base.jsx";


function IndexJsx(props){
    const Page = props.data.pageInner;
    const items = props.data.items;

    const listItems = items.map((item) =>
    <li>
      <a class="thumb" href={`/post/${item.id}`}>
        <img src={item.thumb} />
      </a>
      <div class="title">
        <a href={`/${props.data.type}/${item.id}`}>{item.title}</a>
        <div>{(new Date(item.closedate)).toLocaleDateString('it-IT')}</div>
      </div>
      <div class="edit">
        <a href={`/users/${props.data.type}/edit/${item.id}`}><img src={`/images/edit.png`} /></a>
        <a href={`/users/${props.data.type}/delete/${item.id}`}><img src={`/images/delete.png`} /></a>
      </div>
    </li>
    )

    return(
        <section class="Index">
            <link rel="stylesheet" href="/css/users/index.css" />
            <header>
                <div class="inner region">
                    <div class="title">{props.data.page_title}</div>
                    <form action="/admin/search" method="post">
                        <select name="admin_search">
                            <option>All</option>
                            <option>Category</option>
                        </select>
                        <input type="text" name="admin_q" required placeholder="Search" />
                        <input type="submit" value="Search" />
                    </form>
                    <div class="logout"><span>{props.data.username}</span> | <a href="/">Home</a> | <a href="/users/logout">Logout</a></div>
                </div>
            </header>

            <div class="main region">
                <div class="sidebar">
                    <div class="inner">
                        <a href="/users/post"><img src="/images/post.png" /></a>
                        <a href="/users/post">Post</a>

                        <a href="/users/category"><img src="/images/category.png" /></a>
                        <a href="/users/category">Category</a>

                        <a href="/users/upload"><img src="/images/upload.png" /></a>
                        <a href="/users/upload">Upload</a>

                        <a href="/users/user"><img src="/images/users.png" /></a>
                        <a href="/users/user">User</a>

                        <a href="/users/setting"><img src="/images/setting.png" /></a>
                        <a href="/users/setting">Setting</a>
                    </div>
                </div>
                <div class="content">
                    <Page data={props.data} />
                </div>
            </div>

            <div class="footer region">
                <div class="info">Total amount of items: {props.data.count}</div>
                <ul class="list">
                    { listItems }
                </ul>
                <div class="pagination" dangerouslySetInnerHTML={{__html: `
                    <img onclick="paginate('${props.data.route}')" src="/images/load-more.png" />
                `}}/>

                <div class="credit">&copy; <a href="https://khmerweb.vercel.app/">Khmer Web 2022</a></div>
            </div>
        </section>
    )
}

export default function Index(props){
    props.data.page = IndexJsx;
    return(<Base data={ props.data } />);
}

좋은 웹페이지 즐겨찾기