반응형

 

특정 API에서 파일 다운로드를 제공할 때, 이를 받아들이는 Javascript 예제.

파일명은 API의 Header에 'Content-Disposition' 값에서 가져온다.

 

fetch('/api/download')
  .then(response => {
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }

    // Content-Disposition 헤더에서 파일명 추출
    const contentDisposition = response.headers.get('Content-Disposition');
    const filenameRegex = /filename="?([^"]+)"?/i;
    const matches = filenameRegex.exec(contentDisposition);
    const filename = matches && matches[1];

    return response.blob();
  })
  .then(blob => {
    const url = window.URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute('   
download', filename || 'download.bin'); // 파일명이 없을 경우 기본값 설정
    document.body.appendChild(link);
    link.click();
    window.URL.revokeObjectURL(url);
  })
  .catch(error => {
    console.error('Error:', error);
  });
반응형
반응형

이번 포스팅에서는 지난 포스팅에 이어 11ty를 좀더 활용해서 layout을 구성하고, CSS를 적용하는 방법을 알아보도록 하겠습니다.

1. .eleventy.js파일 생성

프로젝트 루트에 .eleventy.js 파일을 생성합니다. 여기서 Input / Output 폴더와 CSS 파일의 경로를 지정해줍니다.

module.exports = function(eleventyConfig) {  
  eleventyConfig.addPassthroughCopy("./src/style.css");

  return {
    dir: {
      input: "src",
      includes: "_includes",
      data: "_data",
      output: "_site"
    }
  };
};

 

2. 폴더 구성

폴더구성은 아래와 같이 /src/폴더 하위에 작업중인 파일들을 넣습니다. 주의할 것은 /_includes/ 폴더도 /src/ 하위에 위치해야합니다. 이제 아래의 구성에 따라 layout.njk, index.md, style.css 및 포스트 파일들을 작성하도록 하겠습니다.

 

3. /src/_includes/layout.njk

여러 포맷을 지원하지만 예제에서는 nunjucks(njk)파일을 사용합니다. 아래와 같이 프로젝트 전체에서 활용할 layout을 만들어줍니다.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="/style.css">
</head>
<body>
  <header>
    <h1>{{ title }}</h1>
  </header>
  <main>
    {{ content | safe }}
  </main>
</body>
</html>

 

4. src/index.md

메인 페이지에서 사용하는 레이아웃도 위에서 만든 layout.njk입니다. 그러나 내부에 보여줄 컨텐츠가 각 포스트들의 타이틀과 컨텐츠의 목록입니다.

---
layout: "layout.njk"
title: The Best Eleventy Demo
---

{% for post in collections.post %}
<h2><a href="{{ post.url }}">{{ post.data.title}}</a></h2>
<p>{{ post.content }}</p>
{% endfor %}

 

5. src/style.css

CSS파일도 적당히 구성하여 /src폴더에 넣어줍니다.

*{
  font-family:Georgia, 'Times New Roman', Times, serif;
}

header {  
  position: relative;      
  text-align: center;
  font-size: x-large;
}

main {
  position: relative;    
  margin-top: 50px;
  font-size:15px;
  text-align: center;
}
a {
  text-decoration: none;
}

 

6. src/posts/

# post1.md (아래의 형식으로 몇개 더 만들어놓습니다.)

---
title: Post Title
---
asdfxvzxcv

# posts.json

posts폴더 내부의 파일들이 사용할 레이아웃과, 각 파일들의 태그 정보를 설정해줍니다. 여기서는 "tags"값으로 "post"를 지정하였습니다. 이 값은 collections라는 변수로 사용할 수 있습니다. 위의 index.md에서 보시듯이 {{ collections.post }}와 같이 값을 불러와 사용합니다.

{
  "layout": "layout.njk",
  "tags": "post"
}

 

<결과>

 

아직 여러가지 plugin (검색창, 댓글 등)을 확인해보지는 않았지만, 비교적 단순하게 구축이 가능한 정적사이트 생성기로 보입니다. 

반응형
반응형

정적사이트 생성기가 여러개다보니 이것저것 시도해봅니다. 그중에 이번엔 11ty라는 정적사이트 생성기에 대해 알아보겠습니다. 사용법이 매우 쉽습니다.

 

[ 목차 ]

     

    1. 설치

    프로젝트로 쓸 폴더를 생성 후 11ty를 깔아줍니다. (기본적으로 Node는 깔려있어야 합니다.)

    npm init -y
    npm install @11ty/eleventy --save-dev

     

    2. 샘플 파일 생성

    2가지 파일을 생성해야합니다. 리눅스라면 아래의 명령어로 생성이 가능한데, 윈도우 환경이면 직접 두 파일을 만듭니다.

    # index.html
    echo '<!doctype html><title>Page title</title><p>Hi</p>' > index.html
    #README.md
    echo '# Page header' > README.md

     

    3. 서버 실행

    npx @11ty/eleventy --serve
    
    or
    
    npx eleventy --serve

    이렇게만 작성하고 실행해도 index.html을 확인할 수 있습니다. 다른 방법으로는 기존의 방식대로 package.json에 script를 작성해서 사용해도 됩니다.

    {
      "scripts":{
        "dev":"eleventy --serve",
        "build":"eleventy"
      },
      "devDependencies": {
        "@11ty/eleventy": "^2.0.1"
      }
    }

     

    4. post 작성

    기초적인 사용법을 알아볼 겸 이제부터 프로젝트에 조금씩 살을 붙이도록 하겠습니다. 오늘 구성할 프로젝트 구조는 아래와 같습니다. 

    우선 샘플 포스트를 아래와 같이 작성합니다.

    # post1.md
    
    ---
    title: Post Title
    ---
    asdfxvzxcv

     

    # post2.md
    
    ---
    title: My second post
    ---
    zxcvgdfg2343

     

    5. 레이아웃 파일 생성

    /_includes/layout.html파일을 생성합니다. 이 레이아웃으로 모든 md파일의 title과 content를 표시할 예정입니다.

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
    <body>
      <header>
        <h1>{{ title | default: "My Blog" }}</h1>
      </header>
      <main>
        {{ content }}
      </main>
    </body>
    </html>

     

    그리고 /posts/posts.json파일을 아래와 같이 작성합니다.

    {
      "layout": "layout.html",
      "tags": "post"
    }

    layout은 layout.html파일을 이용하겠다는 뜻이고, post라는 태그가 들어있는 파일들의 리스트를 사용하겠다는 의미입니다.

     

    또한 index.html파일은 layout을 이용해 표시할 예정이므로 아무 내용 없이 layout만 지정합니다.

    <!-- index.html -->
    ---
    layout: layout.html
    ---

     

    이렇게 작성하고 아래의 url에서 잘 표시되는지 확인해 봅시다.

    [http://localhost:8080/posts/post1/]

     

    [http://localhost:8080/posts/post2/]

    레이아웃이 잘 적용되었죠?

     

    6. 포스트 리스트

    마지막으로 메인화면에 포스트 목록을 보여주도록 하겠습니다. 이때 태그로 지정했던 post를 이용해서 리스트를 가져옵니다. index.html을 아래와 같이 수정해줍니다.

    <!-- index.html -->
    ---
    layout: layout.html
    ---
    
    {% for post in collections.post %}
    <h2><a href="{{ post.url }}">{{ post.data.title}}</a></h2>
    <p>{{ post.content }}</p>
    {% endfor %}

     


    한번 사용해본 바로는, 이 기능만 있어도 될만큼 엄청 쉽네요. 나머진 CSS로 꾸미기만 해도 될 것 같습니다. 엄청 빠르고 쉬운 11ty. 한번 사용해볼만 한 것 같습니다. 

    반응형
    반응형

    Static Site Generator

    [ 목차 ]

      오늘은 정적사이트 생성기 (SSG, Static Site Generator)에 대해 알아보겠습니다.

       

      1. 정적사이트(SSG) 생성기란?

      정적사이트 생성기는 말 그대로 정적 사이트를 생성하는 도구를 말하는데요, 정적 사이트란 항상 동일한 내용을 보여주는 사전에 빌드된 HTML, Javascript 및 CSS 코드로 구성된 사이트를 일컫는 말입니다. 이러한 웹페이지는 이미 서버 측에서 미리 렌더링된 후 브라우저에 제공되기 때문에 페이지를 더 빠르게 로드할 수 있습니다. 그래서 개인 블로그 등 컨텐츠 변화가 자주 일어나지 않는 소규모 웹사이트 제작시 많이 이용되고 있습니다. 대표적인 도구로는 Jekyll, Gatsby, Hugo 등이 있습니다.

       

        이것만 알면 뭔가 부족한거 같아서 몇가지 개념을 좀 더 알아보겠습니다. 정적 사이트 생성기가 있으면 동적 사이트 생성기도 있을까요? 비슷한 의미로 쓰이는 SSR이라는 개념이 있습니다. SSR은 Server Side Rendering의 약자인데 말 그대로 클라이언트로부터 요청이 들어오면(들어올 때마다) 실시간으로 서버에서 웹페이지를 만들어내는 기술입니다. 대표적으로는 React 기반의 Next.js와 Vue.js 기반의 Nuxt.js, 그리고 Svelte 기반의 SvelteKit이 있습니다. React, Vue.js, Svelte는 SPA라고 합니다. SPA는 Single Page Application의 약자로 우리말로 하면 단일페이지 어플리케이션이 되겠습니다. 웹사이트의 전체 페이지를 하나의 페이지에 담아 클라이언트측에 내려주고, 클라이언트의 반응에 따라 동적으로 화면(데이터)을 변경하는 기술을 말합니다. SSR과는 달리 페이지를 클라이언트측에서 모두 처리하죠. 

       

       

      2. 정적 사이트 생성기의 종류

      정적 사이트 생성기는 아래 그림에서 보이듯이 매우 다양합니다. Next.js와 .Nuxt.js는 SSR기술이라고 설명드렸는데, 주 용도는 SSR이지만 SSG로 사용할 수도 있는 옵션(방법)을 제공합니다.

       

      - React 기반: Next.js, Gatsby, Docusaurus

      - Vue.js 기반: Nuxt.js, Vuepress, Gridsome

      - Javascript 기반: Hexo, Docsify, Eleventy

      - Go 기반 : Hugo

      - Ruby on Rails 기반 : Jekyll

      - Python 기반 : pelican

       

      [ 정적사이트 생성기 Github Star Ranking ]

      Static Site Generator

      저도 SSG를 React, Vue.js 등을 공부하며 알게된 터라 Gatsby 그리고 오래전부터 쓰인 Jekyll정도 알고 있었는데, 정말 다양한 SSG가 존재하네요. 그리고 Go언어로 작성된 Hugo의 인기가 굉장한 것 같아요. 속도 하면 역시 Go언어를 따라올 만한게 별로 없을 것 같네요.

       

      3. 정적 사이트 생성기 (SSG) 테마

      정적사이트 생성기는 다양한 테마를 적용가능한 장점도 있습니다. 이 테마를 이용한 Starter Kit을 통째로 설치해서 쉽게 시작할 수 있죠. 다양한 SSG의 테마를 한곳에서 확인할 수 있는 사이트에 대해 알려드리려고 합니다.

       

      Jamstack Themes

       

      Jamstack Themes

      Over 1000 themes and starters for Jamstack and static site generators.

      jamstackthemes.dev

      위 사이트에서는 각종 정적사이트 생성기(SSG, Static Site Generator)에서 사용 가능한 테마를 보여줍니다. 해당 사이트로 이동하여 상단에 All Themes를 클릭하세요. 전체 테마 리스트를 보여줍니다. 

      Static Site Generator Theme

      테마의 수로는 Jekyll > Hugo > Gatsby > Next.. 순입니다. Github Start 랭킹과도 통하는게 있네요. 오래전부터 쓰이던 Jekyll이 테마가 제일 많고, Go언어의 Hugo가 역시 엄청난 인기에 힘입어 테마도 많다고 판단해야겠죠? 뒤이어 Gatsby가 나오네요. 제가 좋아하는 vue관련된 SSG (Vuepress, Gridsome)의 테마는 거의 없다고 봐도 무방하겠네요^^;; (바꿔야되나..) 다양한 테마의 github 레포지토리를 여러분의 레포지토리에 복사 (또는 Netlify에 배포하면서 동시 복사)해서 사용해보시기 바랍니다.

       

      분이라면 어떤게 좋을 것 같나요? 이쁜 테마를 골라서 Netlify나 Github 등에 배포하고 나만의 멋진 블로그를 만들어보세요.^^

       

      그럼 이만~~

       

       

      반응형
      반응형

      오늘은 자바스크립트에서 자르고 나누는 함수지만 헷갈리는 세가지 함수, slice, splice, split 에대해 알아보도록 하겠습니다.

      [ 목차 ]

        1. slice()

        slice는 원하는 부분을 복사하여 새로운 배열로 리턴합니다. 원본을 변경시키지 않습니다.

        //slice(시작점, 끝점) ...0부터 시작
        
        let my_array=['test1', 'test2','test3','test4'];
        second_array=my_array.slice(2,3)
        
        // output:['test3','test4']

         

        2. splice()

        splice는 원본이 수정됩니다.

        //splice(시작점, 잘라낼 갯수, 추가할 요소,,,n개)
        
        
        // 요소 제거
        let my_array=['test1', 'test2','test3','test4'];
        my_array.splice(1,3);
        console.log(my_array);
        
        // output: ['test1']
        
        
        // 요소 제거 후 신규요소 추가
        let my_array=['test1', 'test2','test3','test4'];
        my_array.splice(1,3,'test5','test6');
        console.log(my_array);
        
        // output: ['test1','test5','test6']
        
        
        // 신규 요소 추가
        let my_array=['test1', 'test2','test3','test4'];
        my_array.splice(1,0,'test5','test6');
        console.log(my_array);
        
        // output: ['test1', 'test5', 'test6', 'test2', 'test3', 'test4']

         

        3. split()

        split은 문자열을 다루는 메서드로, 구분 문자를 기준으로 잘린 배열을 반환합니다. 원본 문자열이 바뀌거나 하진 않습니다.

        // split("구분 문자");
        
        
        // 공백으로 나누기
        const my_string = "Goodmorning everyone. Nice to meet you";
        my_array=my_string.split(" ")
        console.log(my_array);
        
        // output: [ 'Goodmorning', 'everyone.', 'Nice', 'to', 'meet', 'you' ]
        
        
        // 모든문자로 나누기
        const my_string = "Goodmorning everyone. Nice to meet you";
        my_array=my_string.split("")
        console.log(my_array);
        
        // output: 
        // [
        //   'G', 'o', 'o', 'd', 'm', 'o', 'r',
        //   'n', 'i', 'n', 'g', ' ', 'e', 'v',
        //   'e', 'r', 'y', 'o', 'n', 'e', '.',
        //   ' ', 'N', 'i', 'c', 'e', ' ', 't',
        //   'o', ' ', 'm', 'e', 'e', 't', ' ',
        //   'y', 'o', 'u'
        // ]
        
        // 문자열 뒤집기
        const my_string = "Goodmorning everyone. Nice to meet you";
        my_array=my_string.split("").reverse().join("");  // 나누고, 뒤집고, 다시합친다.
        console.log(my_array);
        
        // output: "uoy teem ot eciN .enoyreve gninromdooG"
        반응형
        반응형

        오늘은 Nuxt 프로젝트를 Netlify에 배포해보도록 하겠습니다. 동시에, 도메인 하나를 구매해서 적용해보겠습니다.

        [ 목차 ]

           

          1. 도메인 구매 (hosting.kr)

          저는 Hosting.KR이란 곳에서 도메인을 구매했습니다. 아래와 같이 이벤트중인 도메인 종류들도 있는데, 중간 즈음에 "도메인 가격안내"를 클릭하면 이벤트중인 싸고 좋은 것들도 찾으실 수 있습니다. 

          저는 likeapianist.blog라는 이름으로 블로그를 하나 만들어보겠습니다.

           

          2. Netlify-Gitlap 연동 배포

          사전에 Nuxt 프로젝트를 gitlap(또는 github)에 배포를 해 놓습니다. 어느정도 배포가 가능한 모양새는 갖추고 있어야겠죠?

          본인의 깃 저장소를 고르고...

           

           

          Vue 프로젝트의 빌드는 "npm run build"이지만, nuxt 프로젝트 배포시의 빌드 명령어 "npm run generate"입니다.

          npm run generate

           

          잠시 기다리면 배포가 완성됩니다.

           

          3. 도메인 설정 (Hosting.kr)

          Netlify에서 도메인 설정을 하기에 앞서 우선 Hosting.kr에서 Netlify의 네임서버를 등록합니다.

          dns1.p01.nsone.net
          
          dns2.p01.nsone.net
          
          dns3.p01.nsone.net
          
          dns4.p01.nsone.net

           

          그러면 Netlify에서 인식할 준비가 되었습니다.

           

          다음으로 Netlify로 넘어와서 해당 사이트를 클릭하고,

          Domain management > Domains > Add a domain을 클릭합니다.

          구매한 도메인을 넣고 Verify버튼을 눌러주고, Add domain을 눌러주면 됩니다. (처음 시도시에는 등록되지 않았다는 메시지가 나오지만 무시하고 Add domain을 누릅니다.)

           

          다음으로 Check DNS configuration을 클릭하면 정상적으로 등록이 됩니다.

           

          4. 접속확인

          다음으로 해당 주소로 접속하면.... 

           

          옴마야 세상에~~~ 내가 산 주소로 블로그가 보입니다~~~~~

          반응형
          반응형

          전개연산자는 ES6에서 추가된 기능으로 배열이나 객체를 분해된 값으로 전달하는 기능입니다. 배열 등 모든 순환 가능한 것들은 펼쳐서 가져올 수 있습니다. 

           

          1. 배열 예

          const arr1 = ['a', 'b', 'b'];
          const arr2 = ['d', 'e', 'f'];
          const arr3 = ['g', 'h', 'i'];
          const sum_array = [...arr1, ...arr2, ...arr3];
          
          console.log(sum_array); 
          // ['a', 'b', 'b', 'd', 'e', 'f', 'g', 'h', 'i']

           

          2. 객체배열 예

          const obj_array=[
            {
              name: "one",
              age: 1,
            },
            {
              name: "two",
              age: 2,
            },
            {
              name: "three",
              age: 3,
            }
          ]
          
          const obj_array2=[
            {
              name: "four",
              age: 4,
            }
          ]
          
          
          let new_array = [];
          new_array.push(...obj_array,...obj_array2);
          
          
          console.log(new_array);
          
          //[
          //  { name: 'one', age: 1 },
          //  { name: 'two', age: 2 },
          //  { name: 'three', age: 3 },
          //  { name: 'four', age: 4 }
          //]

           

          반응형
          반응형

          오늘은 자바스크립트 ES6에서 추가된 주요 기능 중 화살표함수( => )에 대해 알아보겠습니다. 

           

          [ 목차 ]

             

            1. 화살표 함수

            기존의 function으로 함수를 표현하는 방식을 좀 더 간결하게 표현하기 위해 화살표( => ) 함수가 도입되었습니다. 아래의 두 함수는 모두 동일한 역할을 하는 함수입니다.

            const test1 = function(a,b){
            	return a+b;
            }
            
            const test2 = (a,b) => {
            	return a+b;
            };
            
            const test3 = (a,b) => a+b;

             

            2. 화살표 함수 주의점(this)

            일반적인 자바스크립트 함수에서의 this는

               - 전역 객체

               - 메소드 호출시 호출한 해당 객체

            를 나타냅니다.

            // 일반 함수
            const obj1 = {
              name: '홍길동',
              func1(){
                console.log(this.name);
              }
            };
            obj1.func1();
            // 홍길동
            
            const obj2 = {
              name: '홍길동',
              func1: function() {
                const func2 = function() {
                  console.log(this.name);
                }
                func2();
              }
            };
            
            obj2.func1();	
            // undefined

            위 두번째 obj2에서 this는 함수를 호출했을 때 지정되지 않았습니다. 곧 전역객체인 Window를 가리킵니다. 하지만 전역 객체 Window에 name이란 속성이 존재하지 않아서 undefined가 나타납니다.

             

            반면 화살표 함수에는 this는 현재 환경에서 그 변수가 없으면 바로 상위 환경을 검색하고, 해당 스코프에서 없으면 다시 또 상위를 검색합니다.

            // 화살표 함수
            const obj2 = {
              name: '이순신',
              func1: function() {
                const func2 = ()=> {
                  console.log(this.name);
                }
                func2();
              }
            };
            
            obj2.func1();	// 이순신

             

            javascript에서의 this는 상당히 헷갈리고 어려운 개념으로 가볍게 다루기엔 좀 부담되는 주제이긴 합니다. 자세한 사용법은 다음에 공부해서 포스팅 하도록 하고, 오늘은 이만 마치겠습니다.

             

             

            (ps) 참고로 메서드 축약선언

            var obj = {
              foo: function() {},
              bar: function() {}
            };
            
            // 이를 아래로 줄일 수 있습니다:
            
            var obj = {
              foo() {},
              bar() {}
            };




            반응형

            + Recent posts