๐ฌ ๋จํธ์ํ ๊ณต๋ชจ์ ์ถํ์ ๊ฐค๋ฌ๋ฆฌ
short-film-contest-gallery
๋ฌธ์ ์ค๋ช
ํ๋ก์ ํธ ๊ฐ์
๋จํธ์ํ ๊ณต๋ชจ์ ์ถํ์์ ํ๋์ ๋ณผ ์ ์๋ ๊ฐค๋ฌ๋ฆฌ ํ์ด์ง๋ฅผ ๋ง๋ญ๋๋ค. ์ํ ํฌ์คํฐ, ์ ๋ชฉ, ๊ฐ๋ , ๋ฌ๋ํ์, ์๋์์ค๋ฅผ ์นด๋ ํํ๋ก ๋ณด์ฌ์ฃผ๊ณ , ๊ด๋๊ฐ๋ค์ด ์ข์์๋ฅผ ๋๋ฅผ ์ ์๋ ์ธํฐ๋ํฐ๋ธ ๊ธฐ๋ฅ์ ๊ตฌํํฉ๋๋ค.
ํ์ ๊ธฐ๋ฅ
- ์ถํ์ ๋ชฉ๋ก ํ์ด์ง: ๊ทธ๋ฆฌ๋ ๋ ์ด์์์ผ๋ก ์ํ ์นด๋ ํ์
- ์ํ ์นด๋: ํฌ์คํฐ ์ด๋ฏธ์ง, ์ ๋ชฉ, ๊ฐ๋ ๋ช , ๋ฌ๋ํ์, ์ฅ๋ฅด ํ๊ทธ
- ์์ธ ํ์ด์ง: ๊ฐ๋ณ ์ํ์ ์๋์์ค์ ์ ์์ง ์ ๋ณด ํ์
- ์ข์์ ๊ธฐ๋ฅ: ๊ฐ ์ํ์ ํํธ ์์ด์ฝ ํด๋ฆญ์ผ๋ก ์ข์์ ๋๋ฅด๊ธฐ
- ์ข์์ ์ ์ ๋ ฌ: ์ธ๊ธฐ ์ํ๋ฅผ ์๋จ์ ํ์ํ๋ ์ ๋ ฌ ๊ธฐ๋ฅ
- ๋ฐ์ํ ๋์์ธ: ๋ชจ๋ฐ์ผ/ํ๋ธ๋ฆฟ/๋ฐ์คํฌํฑ ๋ชจ๋ ์ง์
- ๊ด๋ฆฌ์ ํ์ด์ง: ์ถํ์ ์ถ๊ฐ/์์ /์ญ์ (๊ฐ๋จํ CRUD)
๋ณด๋์ค ๊ธฐ๋ฅ
- ์ฅ๋ฅด๋ณ ํํฐ๋ง (๋๋ผ๋ง, ์ฝ๋ฏธ๋, ์ค๋ฆด๋ฌ ๋ฑ)
- ๊ฒ์ ๊ธฐ๋ฅ (์ ๋ชฉ, ๊ฐ๋ ๋ช ์ผ๋ก ๊ฒ์)
- ๊ณต์ ํ๊ธฐ ๋ฒํผ (SNS ๊ณต์ ๋งํฌ)
- ํ์ด์ง๋ค์ด์ (ํ ํ์ด์ง์ 12๊ฐ์ฉ ํ์)
- ํฌ์คํฐ ํธ๋ฒ ์ ์ ๋๋ฉ์ด์ ํจ๊ณผ
๊ธฐ์ ์คํ
- ๋ฐฑ์๋: Laravel 13.x
- ํ๋ก ํธ์๋: Blade ํ ํ๋ฆฟ + Tailwind CSS
- ๋ฐ์ดํฐ๋ฒ ์ด์ค: SQLite
- ์ด๋ฏธ์ง ์ฒ๋ฆฌ: Laravel Storage (public disk)
ํ์ต ๋ชฉํ
- Laravel ๋ผ์ฐํ ๊ณผ ์ปจํธ๋กค๋ฌ ์ดํด
- Eloquent ORM์ ํ์ฉํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์กฐ์
- Blade ์ปดํฌ๋ํธ๋ก ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ UI ๊ตฌ์ฑ
- ์ด๋ฏธ์ง ์ ๋ก๋์ ์คํ ๋ฆฌ์ง ๊ด๋ฆฌ
- Tailwind CSS๋ก ํ๋์ ์ธ UI ๋์์ธ
์ ์ฝ ์กฐ๊ฑด
- โข Laravel 13.x ์ต์ ๋ฒ์ ์ฌ์ฉ ํ์
- โข Blade ํ ํ๋ฆฟ ์์ง ์ฌ์ฉ (React/Vue ์ฌ์ฉ ๊ธ์ง)
- โข Tailwind CSS๋ก ์คํ์ผ๋ง
- โข SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฌ์ฉ
- โข ์ด๋ฏธ์ง๋ public storage์ ์ ์ฅ
- โข ์ต์ 5๊ฐ ์ด์์ ์ํ ์ํ ๋ฐ์ดํฐ ์๋ฉ
- โข ๋ฐ์ํ ๋์์ธ (๋ชจ๋ฐ์ผ ์ฐ์ )
ํ๋กฌํํธ ๋ ์ํผ
์๋ ํ๋กฌํํธ๋ฅผ ์์๋๋ก AI์๊ฒ ๋ณด๋ด๋ฉด ๋ฉ๋๋ค. ๋ณต์ฌ ๋ฒํผ์ ๋๋ฌ ๋ฐ๋ก ์ฌ์ฉํ์ธ์.
mkdir short-film-contest-gallery && cd short-film-contest-gallery ์ด ํด๋์์ Laravel 13.x ํ๋ก์ ํธ๋ฅผ ์์ํฉ๋๋ค. ๋ค์ ์๊ตฌ์ฌํญ์ผ๋ก Laravel ํ๋ก์ ํธ๋ฅผ ์์ฑํด์ฃผ์ธ์: 1. Laravel 13.x ์ต์ ๋ฒ์ ์ผ๋ก ํ๋ก์ ํธ ์ด๊ธฐํ 2. SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค์ (.env ํ์ผ ์์ ) 3. Tailwind CSS ์ค์น ๋ฐ ์ค์ (Vite ์ฌ์ฉ) 4. ํ์ํ ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ ์์ฑ: - films ํ ์ด๋ธ: id, title, director, runtime (๋ถ ๋จ์), genre, synopsis, poster_path, likes_count, timestamps 5. Film ๋ชจ๋ธ ์์ฑ (Eloquent) 6. ๊ธฐ๋ณธ ๋ ์ด์์ Blade ํ์ผ ์์ฑ (app.blade.php) - Tailwind CSS ํฌํจ - ์๋จ ๋ค๋น๊ฒ์ด์ ๋ฐ (๋ก๊ณ , ๋ฉ๋ด) - ํธํฐ 7. ํ์ ํ์ด์ง ๋ผ์ฐํธ ์ค์ (GET /) ํ๋ก์ ํธ ๊ตฌ์กฐ๋ฅผ ์ก๊ณ ๊ธฐ๋ณธ ์ค์ ์ ์๋ฃํด์ฃผ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: Laravel ํ๋ก์ ํธ๊ฐ ์์ฑ๋๊ณ , SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ด ์ค์ ๋๋ฉฐ, Tailwind CSS๊ฐ ํตํฉ๋ฉ๋๋ค. films ํ ์ด๋ธ ๋ง์ด๊ทธ๋ ์ด์ ๊ณผ Film ๋ชจ๋ธ์ด ์์ฑ๋๊ณ , ๊ธฐ๋ณธ ๋ ์ด์์ ํ์ผ์ด ์ค๋น๋ฉ๋๋ค.
์ด์ ์ถํ์ ๊ฐค๋ฌ๋ฆฌ์ ๋ฉ์ธ ํ์ด์ง๋ฅผ ๋ง๋ค์ด๋ด
์๋ค.
๋ค์์ ๊ตฌํํด์ฃผ์ธ์:
1. FilmController ์์ฑ (php artisan make:controller FilmController)
2. ๋ผ์ฐํธ ์ถ๊ฐ:
- GET /films โ FilmController@index (๊ฐค๋ฌ๋ฆฌ ๋ชฉ๋ก)
- GET /films/{id} โ FilmController@show (์์ธ ํ์ด์ง)
3. index ๋ฉ์๋ ๊ตฌํ:
- ๋ชจ๋ ์ํ๋ฅผ ์ข์์ ์์ผ๋ก ์ ๋ ฌํ์ฌ ๊ฐ์ ธ์ค๊ธฐ
- films/index.blade.php ๋ทฐ์ ์ ๋ฌ
4. films/index.blade.php ์์ฑ:
- ๊ทธ๋ฆฌ๋ ๋ ์ด์์ (๋ชจ๋ฐ์ผ: 1์ด, ํ๋ธ๋ฆฟ: 2์ด, ๋ฐ์คํฌํฑ: 3์ด)
- ์ํ ์นด๋ ์ปดํฌ๋ํธ: ํฌ์คํฐ, ์ ๋ชฉ, ๊ฐ๋
, ๋ฌ๋ํ์, ์ฅ๋ฅด ํ๊ทธ, ์ข์์ ์
- Tailwind CSS๋ก ์ธ๋ จ๋ ์นด๋ ๋์์ธ (๊ทธ๋ฆผ์, ํธ๋ฒ ํจ๊ณผ)
- ๊ฐ ์นด๋ ํด๋ฆญ ์ ์์ธ ํ์ด์ง๋ก ์ด๋
5. ์์ ๋ฐ์ดํฐ๋ก 5๊ฐ์ ์ํ ์ํ๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์๋๋ก ์ถ๊ฐ
- DatabaseSeeder์์ Film::factory() ๋๋ ์ง์ ์์ฑ
- ํฌ์คํฐ๋ placeholder ์ด๋ฏธ์ง URL ์ฌ์ฉ (์: https://via.placeholder.com/300x450)
๊ฐค๋ฌ๋ฆฌ๊ฐ ์๊ฐ์ ์ผ๋ก ๋งค๋ ฅ์ ์ด๊ณ ๋ฐ์ํ์ผ๋ก ์๋ํ๋๋ก ํด์ฃผ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: ์ํ ๋ชฉ๋ก์ด ๊ทธ๋ฆฌ๋ ๋ ์ด์์์ผ๋ก ํ์๋๋ ๊ฐค๋ฌ๋ฆฌ ํ์ด์ง๊ฐ ์์ฑ๋ฉ๋๋ค. 5๊ฐ์ ์ํ ์ํ ๋ฐ์ดํฐ๊ฐ ์๋ฉ๋๊ณ , ์นด๋๊ฐ ๋ฐ์ํ์ผ๋ก ๋ฐฐ์น๋๋ฉฐ, ํธ๋ฒ ํจ๊ณผ๊ฐ ์ ์ฉ๋ฉ๋๋ค.
์ํ ์์ธ ํ์ด์ง์ ์ข์์ ๊ธฐ๋ฅ์ ๊ตฌํํฉ๋๋ค.
๋ค์์ ๊ตฌํํด์ฃผ์ธ์:
1. FilmController์ show ๋ฉ์๋ ๊ตฌํ:
- ID๋ก ์ํ ์ฐพ๊ธฐ (Film::findOrFail($id))
- films/show.blade.php ๋ทฐ์ ์ ๋ฌ
2. films/show.blade.php ์์ฑ:
- ํฐ ํฌ์คํฐ ์ด๋ฏธ์ง (์ผ์ชฝ)
- ์ํ ์ ๋ณด (์ค๋ฅธ์ชฝ): ์ ๋ชฉ, ๊ฐ๋
, ๋ฌ๋ํ์, ์ฅ๋ฅด
- ์๋์์ค ์ ์ฒด ํ
์คํธ
- ์ข์์ ๋ฒํผ (ํํธ ์์ด์ฝ)
- ์ข์์ ์ ํ์
- ๋ชฉ๋ก์ผ๋ก ๋์๊ฐ๊ธฐ ๋ฒํผ
3. ์ข์์ ๊ธฐ๋ฅ ๊ตฌํ:
- POST /films/{id}/like ๋ผ์ฐํธ ์ถ๊ฐ
- FilmController@like ๋ฉ์๋ ์์ฑ
- likes_count ์ปฌ๋ผ +1 ์ฆ๊ฐ
- ํ์ด์ง ์๋ก๊ณ ์นจ ๋๋ ๊ฐ์ ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ํธ
4. Blade์์ ์ข์์ ๋ฒํผ์ ํผ์ผ๋ก ๊ตฌํ (CSRF ํ ํฐ ํฌํจ)
5. Tailwind CSS๋ก ์ธ๋ จ๋ ์์ธ ํ์ด์ง ๋ ์ด์์ ๋์์ธ
์์ธ ํ์ด์ง๊ฐ ๊น๋ํ๊ณ ์ข์์ ๊ธฐ๋ฅ์ด ์ ์ ์๋ํ๋๋ก ํด์ฃผ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: ์ํ๋ฅผ ํด๋ฆญํ๋ฉด ์์ธ ํ์ด์ง๋ก ์ด๋ํ๋ฉฐ, ํฌ์คํฐ์ ์๋์์ค๊ฐ ๋ณด๊ธฐ ์ข๊ฒ ํ์๋ฉ๋๋ค. ์ข์์ ๋ฒํผ์ ๋๋ฅด๋ฉด ์นด์ดํธ๊ฐ ์ฆ๊ฐํ๊ณ , ๊ฐค๋ฌ๋ฆฌ ๋ชฉ๋ก์๋ ๋ฐ์๋ฉ๋๋ค.
๋ง์ง๋ง์ผ๋ก ๊ด๋ฆฌ์ ํ์ด์ง๋ฅผ ์ถ๊ฐํ์ฌ ์ํ๋ฅผ ๋ฑ๋ก/์์ /์ญ์ ํ ์ ์๋๋ก ํฉ๋๋ค.
๋ค์์ ๊ตฌํํด์ฃผ์ธ์:
1. ๋ผ์ฐํธ ์ถ๊ฐ:
- GET /admin/films โ ๊ด๋ฆฌ์ ์ํ ๋ชฉ๋ก
- GET /admin/films/create โ ์ํ ๋ฑ๋ก ํผ
- POST /admin/films โ ์ํ ์ ์ฅ
- GET /admin/films/{id}/edit โ ์ํ ์์ ํผ
- PUT /admin/films/{id} โ ์ํ ์
๋ฐ์ดํธ
- DELETE /admin/films/{id} โ ์ํ ์ญ์
2. AdminFilmController ์์ฑ (๋๋ FilmController์ ๋ฉ์๋ ์ถ๊ฐ)
3. admin/films/index.blade.php: ํ
์ด๋ธ ํํ๋ก ์ํ ๋ชฉ๋ก ํ์, ์์ /์ญ์ ๋ฒํผ
4. admin/films/create.blade.php: ์ํ ๋ฑ๋ก ํผ
- ์ ๋ชฉ, ๊ฐ๋
, ๋ฌ๋ํ์, ์ฅ๋ฅด, ์๋์์ค ์
๋ ฅ ํ๋
- ํฌ์คํฐ ์ด๋ฏธ์ง ํ์ผ ์
๋ก๋ (enctype="multipart/form-data")
5. admin/films/edit.blade.php: ์ํ ์์ ํผ (create์ ์ ์ฌ)
6. ์ด๋ฏธ์ง ์
๋ก๋ ์ฒ๋ฆฌ:
- Storage::disk('public')->put() ์ฌ์ฉ
- php artisan storage:link ์คํ ์๋ด
7. ์ ํจ์ฑ ๊ฒ์ฌ ์ถ๊ฐ (title required, runtime numeric ๋ฑ)
8. ์ญ์ ์ ํ์ธ ๋ชจ๋ฌ ๋๋ JavaScript confirm
๊ด๋ฆฌ์๊ฐ ์ํ๋ฅผ ์ฝ๊ฒ ๊ด๋ฆฌํ ์ ์๋ CRUD ์์คํ
์ ์์ฑํด์ฃผ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: ๊ด๋ฆฌ์ ํ์ด์ง์์ ์ํ๋ฅผ ๋ฑ๋ก, ์์ , ์ญ์ ํ ์ ์์ต๋๋ค. ์ด๋ฏธ์ง ์ ๋ก๋๊ฐ ์ ์ ์๋ํ๊ณ , ์ ํจ์ฑ ๊ฒ์ฌ๋ก ์๋ชป๋ ์ ๋ ฅ์ ๋ฐฉ์งํฉ๋๋ค. ์ ์ฒด CRUD ๊ธฐ๋ฅ์ด ์์ฑ๋ฉ๋๋ค.
์ ์ถ๋ ์ํ (0)
๋ก๊ทธ์ธ ํ ์ ์ถ์์ง ์ ์ถ๋ ์ํ์ด ์์ต๋๋ค. ์ฒซ ๋ฒ์งธ ๋์ ์๊ฐ ๋์ด๋ณด์ธ์!