20.12.27 사이트 메타태그 적용(상세페이지 내용 나오게 하기 등)

2020. 12. 27. 21:36JAVA/Blog 사이트 프로젝트

<HTML>

<!doctype html>
<html lang="en">

<head>
<script data-ad-client="ca-pub-7996879977557531" async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-X5RMP83794"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-X5RMP83794');
</script>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 구글 검색엔진 등록-소유권 확인 -->
<meta name="google-site-verification" content="37R4KcEaJU5LfiKL7GI1hu1_spJgWOazN6xy48OHhD4" />

<!-- Meta Tag & Open Graph -->
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=1200">
<meta name="apple-mobile-web-app-title" content="[사이트 타이틀]" />
<!-- 메타태그정보 //-->
<!-- META -->
<link rel="canonical" href="[사이트 URL]" />
<meta name="subject" content="[사이트 주제]"/>
<meta name="title" content="[사이트 타이틀]" />
<meta name="keywords" content="[사이트 키워드]" />
<meta name="copyright" content="[사이트 타이틀]" />
<meta name="pubdate" content="[날짜]" />
<meta name="lastmod" content="[날짜]" />
<!-- OPENGRAPH -->
<meta property="og:site_name" content="[사이트 타이틀]" />
<meta property="og:type" content="blog" />
<meta property="og:title" content="[사이트 주제]" />
<meta property="og:description" content="[사이트 설명]" />
<meta property="og:locale" content="ko_KR" />
<meta property="og:image" content="images/Dev_J_logo/logo.png" />
<meta property="og:image:alt" content="[사이트 도메인]" />
<meta property="og:image:width" content="486" />
<meta property="og:image:height" content="254" />
<meta property="og:updated_time" content="[날짜]"/>
<meta property="og:pubdate" content="[날짜]" />
<meta property="og:url" content="[사이트 URL]" />
<!-- TWITTER -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="[사이트 주제]" />
<meta name="twitter:site" content="@[사이트 타이틀]" />
<meta name="twitter:creator" content="@[사이트 타이틀]" />
<meta name="twitter:image" content="images/Dev_J_logo/logo.png">
<meta name="twitter:description" content="[사이트 설명]" />
<!-- GOOGLE+ -->
<meta itemprop="headline" content="[사이트 타이틀]" />
<meta itemprop="name" content="[사이트 타이틀]" />
<meta itemprop="description" content="[사이트 설명]" />
<meta itemprop="image" content="images/Dev_J_logo/logo.png" />

<!-- 사이트 타이틀 -->
<title>[페이지 타이틀]</title>


<!-- 파비콘 -->
<link rel="shortcut icon" href="images/favicon/favicon.ico" type="image/x-icon">
<link rel="icon" href="images/favicon/favicon.ico" type="image/x-icon">

<!-- 폰트어썸 불러오기 -->
<link rel="stylesheet"
	href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css">
<!-- app.css 불러오기 -->
<link rel="stylesheet" href="app.css">

<!--모바일에서도 PC와 같은 비율 유지-->
<meta name="viewport" content="width=device-width, initial-scale=1">

<!--제이쿼리-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>


</head>

<body>
<!-- 사이트 박스 시작 -->
<div class="body-content min-height-100vh flex flex-column">
  <!-- 로고바 시작 -->
  <header class="logo-bar con-min-width" id="header">
    <div class="con height-100p flex flex-jc-c">
      <a href="index.html" class="logo flex flex-ai-c"> 
        <img class="logo__img" src="images/Dev_J_logo/facebook_cover_photo_1.png" alt="">
        <span>
          BLOG
        </span>
      </a>
    </div>
  </header>
  <!-- 로고바 끝 -->

  <!-- 메뉴바 시작 -->
  <header class="menu-bar con-min-width">
    <div class="con height-100p">
      <nav class="menu-bar__menu-1">
        <ul class="flex">
          <li>
            <a href="index.html" class="block">
              <i class="fas fa-home"></i>
              <span>HOME</span>
            </a>
          </li>
          <li>
            <a class="block">
              <i class="fas fa-list"></i>
              <span>ARTICLES</span>
            </a>
            <ul>
              [게시판 이름 블록]
            </ul>
          </li>
          <li>
            <a class="block">
              <i class="fas fa-link"></i>
              <span>LINK</span>
            </a>
            <ul>
              <li>
                <a href="https://cjy324.tistory.com/" target="_blank" class="block">
                  <i class="fas fa-rss-square"></i>
                  <span>T-STORY</span>
                </a>
              </li>
              <li>
                <a href="https://github.com/cjy324/TIL_Jooyoung#til_jooyoung" target="_blank" class="block">
                  <i class="fab fa-github"></i>
                  <span>GITHUB</span>
                </a>
              </li>
            </ul>
          </li>
          <li>
            <a href="https://analytics.google.com/analytics/web/?hl=ko&pli=1#/p256591365/reports/defaulthome?params=_u..nav%3Ddefault" target="_blank" class="block">
              <i class="fas fa-chart-pie"></i>
              <span>STATISTICS</span>
            </a>
          </li>
        </ul>
      </nav>
    </div>
  </header>
  <!-- 메뉴바 끝 --> 

  <!-- 메인 컨텐츠 박스 시작 -->
  <main class="flex-grow-1">
   <!-- 메인-타이틀바 시작 -->
	<div class="title-bar con-min-width">
		<h1 class="con">
			[타이틀바 컨텐츠]
		</h1>
	</div>
   <!-- 메인-타이틀바 종료 -->

 

<BulidService.java>

package com.sbs.example.mysqlTextBoard.service;

import java.util.Collections;
import java.util.List;

import com.sbs.example.mysqlTextBoard.container.Container;
import com.sbs.example.mysqlTextBoard.dto.Article;
import com.sbs.example.mysqlTextBoard.dto.Board;
import com.sbs.example.mysqlTextBoard.util.Util;

public class BuildService {
	ArticleService articleService;

	public BuildService() {
		articleService = Container.articleService;

	}

	public void builSite() {
		System.out.println("= site 폴더 생성 =");

	//	Util.rmdir("site"); // 기존 site 폴더 삭제
		Util.mkdir("site"); // 신규 site 폴더 생성

		// site_template에 있는 app.css(원본)를 복사해 site폴더 생성시 그 안에 복사본 붙여넣기
		Util.copy("site_template/app.css", "site/app.css");
		Util.copy("site_template/app.js", "site/app.js");
		
		// site_template에 있는 images(원본)폴더를 복사해 site폴더 생성시 그 안에 복사본 붙여넣기
		Util.copyDir("site_template/images", "site/images");
		
		buildIndexPage(); // 인덱스 페이지 생성
		buildArticleListPages(); // 각 게시판 별 게시물리스트 페이지 생성
		buildArticleDetailPages(); // 게시판 별 게시물 상세페이지 생성

	}


-----------------------------------------------------------------------------------

	// 게시판 별 게시물 상세페이지 생성
	private void buildArticleDetailPages() {
		List<Board> boards = articleService.getBoards();

		for (Board board : boards) {
			List<Article> articles = articleService.getBoardArticlesByCodeForPrint(board.code);
			int articlesSize = articles.size();
			
			if (articlesSize <= 0) {
				continue;
			}
			int beforeArticleIndex = 0;
			int x = beforeArticleIndex;
			int beforeArticleId = articles.get(x).id;

		//	String head = getHeadHtml("article_detail");
			String sideBar = getSideBarHtml();
			String topButton = Util.getFileContents("site_template/top-button.html");
			String foot = Util.getFileContents("site_template/foot.html");

			String template = Util.getFileContents("site_template/detail.html");

			System.out.println("= article 상세페이지 생성 =");

			for (Article article : articles) {
				
				String head = getHeadHtml("article_detail", article);
				
				StringBuilder html = new StringBuilder();

				html.append(head);

				StringBuilder body = new StringBuilder();
				
				body.append("<div class=\"article-detail-cell__board-name\">");
				body.append("<div>");
				body.append("<span>게시판 : </span><span>"+ board.name +" 게시판</span>");
				body.append("</div>");
				body.append("</div>");
				body.append("<div class=\"article-detail-cell__id\">");
				body.append("<div>");
				body.append("<span>게시물 번호 : </span><span>" + article.id + "</span>");
				body.append("</div>");
				body.append("</div>");
				body.append("<div class=\"article-detail-cell__member-id\">");
				body.append("<div>");
				body.append("<span>작성자 : </span><span>" + article.extra_memberName + "</span>");
				body.append("</div>");
				body.append("</div>");
				body.append("<div class=\"article-detail-cell__reg-date\">");
				body.append("<div>");
				body.append("<span>작성일 : </span><span>" + article.regDate + "</span>");
				body.append("</div>");
				body.append("</div>");
				body.append("<div class=\"article-detail-cell__update-date\">");
				body.append("<div>");
				body.append("<span>수정일 : </span><span>" + article.updateDate + "</span>");
				body.append("</div><br>");
				body.append("</div>");
				body.append("<div class=\"article-detail-cell__title\">");
				body.append("<div>");
				body.append("<span>제목 : </span><span>" + article.title + "</span>");
				body.append("</div>");
				body.append("</div>");
				body.append("<div class=\"article-detail-cell__body height-70p \">");
				body.append("<div>");
				body.append("<span>" + article.body + "</span>");
				body.append("</div>");
				body.append("</div><br><br>");
				//댓글 유틸 disqus 적용
				body.append("<nav><div id=\"disqus_thread\"></div>\r\n"
						+ "<script>\r\n"
						+ "    (function() { // DON'T EDIT BELOW THIS LINE\r\n"
						+ "    var d = document, s = d.createElement('script');\r\n"
						+ "    s.src = 'https://devj-blog.disqus.com/embed.js';\r\n"
						+ "    s.setAttribute('data-timestamp', +new Date());\r\n"
						+ "    (d.head || d.body).appendChild(s);\r\n"
						+ "    })();\r\n"
						+ "</script>\r\n"
						+ "<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\">comments powered by Disqus.</a></noscript></nav>");
				
				
				// 상세페이지 하단 메뉴
				
				StringBuilder pageMenuBody = new StringBuilder();
				
				if (article.id > beforeArticleId) {
					pageMenuBody.append("<div class=\"./\"><a href=\"" + articles.get(x - 1).id + ".html"
							+ "\" class=\"hover-underline\">&lt 이전글</a></div>");
				}

				pageMenuBody.append("<div class=\"./\"><i class=\"fas fa-th-list\"></i><a href=\"" + board.code + "-list-1.html"
						+ "\" class=\"hover-underline\"> 목록 </a></div>");
				if (x < articlesSize - 1) {
					pageMenuBody.append("<div class=\"./\"><a href=\"" + articles.get(x + 1).id + ".html"
							+ "\"class=\"hover-underline\">다음글 &gt</a></div>");
				}

				String bodyTemplate = template.replace("[상세페이지 블록]", body); // list 템플릿에 mainBody 끼워넣고
				html.append(bodyTemplate.replace("[상세페이지 하단 메뉴 블록]", pageMenuBody)); // bodyTemplate에 다시 pageMenuBody 끼워넣기
				html.append(sideBar);
				html.append(topButton);
				html.append(foot);

				String fileName = article.id + ".html";
				String path = "site/" + fileName;

				Util.writeFile(path, html.toString());

				System.out.println(path + " 생성");
				x++;
				beforeArticleId = articles.get(x - 1).id;

			}
			System.out.println("= article 상세페이지 생성 종료 =");

		}
	}
	
	// head.html 가져오기 오버라이드
	private String getHeadHtml(String pageName) {   // 만약, getHeadHtml()에 pageName만 있으면 getHeadHtml(pageName, null)로 리턴
		return getHeadHtml(pageName, null);
	}
	
	// head.html 가져오기
	private String getHeadHtml(String pageName, Object object) {
		List<Board> boards = articleService.getBoards();

		String head = Util.getFileContents("site_template/head.html"); // head.html 가져오기
		StringBuilder boardMenuContentHtml = new StringBuilder();
		
		for (Board board : boards) {
			boardMenuContentHtml.append("<li>");

			String link = board.code + "-list-1.html";

			boardMenuContentHtml.append("<a href=\"" + link + "\" class=\"block\">");
			boardMenuContentHtml.append(getTitleBarContentByPageName("article_list_" + board.code) + " BOARD");
			boardMenuContentHtml.append("</a>");
			boardMenuContentHtml.append("</li>");

		}

		head = head.replace("[게시판 이름 블록]", boardMenuContentHtml.toString());

		String titleBarContentHtml = getTitleBarContentByPageName(pageName);
		// 입력받은 pageName에 맞는 타이틀바 컨텐츠를 리턴

		head = head.replace("[타이틀바 컨텐츠]", titleBarContentHtml);
		
		String pageTitle = getPageTitle(pageName, object);
		// 입력받은 pageName에 맞는 페이지의 타이틀을 리턴
		
		head = head.replace("[페이지 타이틀]", pageTitle);
	
		//Meta Tag & Open Graph 작업
		String siteTitle = "Dev_J BLOG";
		String siteSubject = "Dev_J의 BLOG";
		String siteKeywords = "JAVA, HTML, CSS, JavaScript, MySQL";
		String siteDescription = "Dev_J의 BLOG입니다.";
		String siteDomain = "blog.devj.me"; 
		String siteMainUrl = "https://" + siteDomain;
		String currentDate = Util.getNowDateStr().replace(" ", "T");
		
		
		//게시물 상세페이지마다 내용 나오게 하기
		if ( object instanceof Article ) {
			Article article = (Article) object;
			siteSubject = article.title;
			siteDescription = article.body;
			siteDescription = siteDescription.replaceAll("[^\uAC00-\uD7A3xfe0-9a-zA-Z\\s]", "");
			//[^\uAC00-\uD7A3xfe0-9a-zA-Z\\s] => 모든 특수문자 제거
		}
		
		
		head = head.replace("[사이트 타이틀]", siteTitle);
		head = head.replace("[사이트 주제]", siteSubject);
		head = head.replace("[사이트 키워드]", siteKeywords);
		head = head.replace("[사이트 설명]", siteDescription);
		head = head.replace("[사이트 도메인]", siteDomain);
		head = head.replace("[사이트 URL]", siteMainUrl);
		head = head.replace("[날짜]", currentDate);
		
		
		return head;
	}

	// 입력받은 pageName에 맞는 페이지의 타이틀을 리턴
	private String getPageTitle(String pageName, Object object) {
		StringBuilder pageTitle = new StringBuilder();
		
		String forPrintPageName = pageName;
		
		if(forPrintPageName.equals("index")) {
			forPrintPageName = "home";
		}
		
		forPrintPageName = forPrintPageName.toUpperCase(); //대상 문자열을 모두 대문자로 변환
		forPrintPageName = forPrintPageName.replace("_", " "); //pageName에 있는 _를 공백으로 변환
		
		pageTitle.append("Dev_J BLOG | ");
		pageTitle.append(forPrintPageName);
		
		//object가 Article이라는 객체로 형변환이 가능한지를 판단
		if(object instanceof Article) {
			Article article = (Article) object;
			
			pageTitle.insert(0, article.title + " | ");
			//형변환이 가능하면 0번 위치에? article.title + "|" 삽입
		}
		
		return pageTitle.toString();
	}

	// 페이지이름에 따라 메인부분 타이틀바 아이콘 가져오기
	private String getTitleBarContentByPageName(String pageName) {
		if (pageName.equals("index")) {
			return "";
		} else if (pageName.equals("article_detail")) {
			return "<i class=\"fas fa-file-invoice\"></i> <span>ARTICLE DETAIL</span>";
		} else if (pageName.startsWith("article_list_notice")) {
			return "<i class=\"fas fa-exclamation\"></i> <span>NOTICE</span>";
		} else if (pageName.startsWith("article_list_free")) {
			return "<i class=\"fas fa-users\"></i> <span>FREE</span>";
		} else if (pageName.startsWith("article_list_java")) {
			return "<i class=\"fab fa-java\"></i> <span>JAVA</span>";
		} else if (pageName.startsWith("article_list_")) {
			return "<i class=\"fas fa-clipboard-list\"></i> <span>NONAME BOARD</span>";
		}
		return "";
	}

}