[TIL] 211216


📝 今日作った

  • flash messages - express-flash/req.flash()/messages.key/keyframes/animationプロパティ/position:absolit&margin:0 auto
  • 📚 学識


    1. flash messages


    要求に対する応答としてpugファイルをレンダリングする場合は、テンプレートで変数を共有することでメッセージを送信できます.
    リクエストへの応答としてリダイレクトを使用する場合は、flash messgeを使用してユーザーに理由を伝えることができます.

    1) express-flash


    express-flashをインストールします.
    $ npm i express-flash
    Flashミドルウェアimport後に使用できます.
    これにより、flashミドルウェアはsessionに接続され、そのユーザーにのみメッセージを表示できます.
    これは使い捨てのメッセージで、表示されるとexpressはcacheから削除されます.
    // server.js
    import session from "express-session";
    import flash from "express-flash"; // express-session 보다 뒤에서 import 해야 한다 ❗
    
    app.use(flash());

    2) req.flash()

    req.flash("메시지 타입", "메시지 내용");
    Flashミドルウェア、reqをインストールします.Flash()関数を使用してfalshメッセージを作成できます.
    状況に応じて適切なメッセージを作成し、ミドルウェアとコントローラに追加します.
    middleware.js
    const protectorMiddleware = () => {
      if (req.session.loggedIn) {
        next();
      } else {
        req.flash("info", "Not Authorized");
        return res.redirect("/login");
      }
    };
    
    const publicOnlyMiddleware = () => {
      if (!req.session.loggedIn) {
        next();
      } else {
        req.flash("info", "Not Authorized");
        return res.redirect("/");
      }
    };
    userController.js
    export const finishGithubLogin = async (req, res) => {
      
      // 중략
      
      if ("access_token" in tokenRequest) {
        
        // 중략
        
        // github API의 user의 유효한 이메일이 없을 시
        if (!emailObj) {
          req.flash("error", "No valid email.");
          return res.redirect("/login");
        }
        
        // 중략
        
      } else {
        // 액세스 토큰이 없을 시
        req.flash("error", "No access token");
        return res.redirect("/login");
      }
    };
    
    // 로그아웃 시
    export const logout = (req, res) => {
      req.session.destroy();
      req.flash("info", "Bye bye");
      return res.redirect("/");
    };
    
    // github로 계정 만든 user가 패스워드를 변경하려고 할 때
    export const getChangePassword = async (req, res) => {
      if (req.session.user.socialOnly === true) {
        req.flash("error", "Can't change password.");
        return res.redirect("/");
      }
      return res.render("change-password", { pageTitle: "Change Password" });
    };
    
    // 패스워드 업데이트 시
    export const postChangePassword = async (req, res) => {
      
      // 중략
      
      req.flash("info", "Password updated");
      return res.redirect("/users/logout");
    };
    videoController.js
    // 수정하려는 비디오의 소유자가 아닐 때
    export const getEdit = async (req, res) => {
      // 중략
      
      if (String(video.owner) !== _id) {
        req.flash("error", "Not Authorized");
        return res.status(403).redirect("/");
      }
    
      // 중략
    };
    
    // 수정하려는 비디오의 소유자가 아닐 때
    export const postEdit = async (req, res) => {
      // 중략
      
      if (String(video.owner) !== _id) {
        req.flash("error", "Not Authorized");
        return res.status(403).redirect("/");
      }
      
      // 중략
    };
    
    // 비디오 삭제 시
    export const deleteVideo = async (req, res) => {  
      // 중략
      
      if (String(video.owner) !== _id) {
        req.flash("error", "Not Authorized");
        return res.status(403).redirect("/");
      }
    
      // 중략  
    };

    3) messages.key


    req.Flash()でメッセージを作成すると、そのメッセージを含むメッセージ変数が作成されます.
    メッセージは、pugファイルのmessages.key値を使用して表示できます.
    mixinフォルダにメッセージを表示して、異なるメッセージを同じ形式で表示します.pugファイルを作成したらbase.pugファイルに含まれます.
    message.pug
    mixin message(kind, text)
      div.message(class=kind)
        span=text
    base.pug
    include mixins/message
    
    doctype html
    html(lang="ko")
      head
        //- 중략
      body
        if (messages.error)
          +message("error", messages.error)
        if (messages.info)
          +message("info", messages.info)
        if (messages.success)
          +message("success", messages.success)
        include partials/header
        main
          block content
        include partials/footer

    4)CSS造形

    // styles.scss
    
    @keyframes goAway {
      from {
        transform: none;
        opacity: 1;
      }
      to {
        transform: translateY(-100px);
        opacity: 0;
      }
    }
    
    .message {
      position: absolute;
      right: 0;
      left: 0;
      margin: 0 auto;
      max-width: 200px;
      height: 40px;
      line-height: 40px;
      text-align: center;
      border-radius: 1000px;
      animation: goAway 0.5s 3s ease-in-out forwards;
      color: white;
      &.error {
        background-color: $red;
      }
      &.info {
        background-color: $grey;
      }
      &.success {
        background-color: $blue;
      }
    }

    (1) keyframes

    @keyframes 애니메이션 이름 {
      from {
      
      // 애니메이션 실행 전 스타일
      
      }
      to {
      
      // 애니메이션 실행 후 스타일
      
      }
    }
    キーが正常に動作するには、特定の数値(Detail Number)を指定する必要があります.
    つまり、数値を書くときにautoを使うことはできません.

    (2)アニメーションのプロパティ


    cssアニメーションまとめ(遷移、変換、変換、アニメーション、@キーフレーム)を参照
    animation: 이름 | 지속 시간 | 지연 시간 | 진행 방식 | fill-mode 속성
    지연 시간から진행 방식まで、一定時間が経過するとto指定の지속 시간で発生し、to状態はfill-mode 속성に続く.forwardsは、アニメーションが実行前、後にターゲットにスタイルを適用する方法を指定します.position: absoluteを指定すると、アニメーションが終了しても状態まで継続します.

    (3)position:absoluteにmargin:0 autoを適用


    CSS位置属性のクリア
    要素がmargin: 0 autoの状態にある場合、position: absoluteを指定してもソートされません.
    この場合、エレメントがブロックレベルエレメントであっても、行内レベルエレメントのようにコンテンツと同じ幅しかありません.
    div {
      position: absolute;
      right: 0;
      margin: 0 auto;
    }
    margin: 0 auto元素を集中的に配列するためには、left: 0及びright: 0を添加して、両親の幅を占めるようにする必要がある.
    div {
      position: absolute;
      right: 0;
      left: 0;
      margin: 0 auto;
    }

    明日作った

  • comment section