1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

おっさん初学者のRailsチュートリアル学習記録(5章)

Last updated at Posted at 2021-01-27

プログラミング年少組のど素人が、アウトプット用に素人目線の解説を書いていきます。
自分が自分に教えていることを想像しながら進めていきます。
下記と同じような境遇の方であれば参考になるかも

  • まっさらなプログラミング初学者目線
  • オール独学
  • 勉強は得意じゃない
  • 社会人のため、1日に勉強できる量は限られる。

電子書籍のwebテキスト(第6版)を購入して使用
Progateの「Web開発パス」完走済
ドットインストールのプレミアム会員卒業
Railsチュートリアル解説動画を見ながら学習中
#5章 レイアウトを作成する#
この章では、Webサイトの基本的なレイアウトの作成を見ていきます。
そこで、これまでの章で作成してきたサンプルアプリのレイアウトを整えていきます。
MVCで言えば「View」の部分に該当します。
と言っても決して単純な作業ではなくて、Bootstrapフレームワークやら、パーシャルを使ったリファクタリング、AsstPipelineがあるなしでどう違うのか、Sassなど聞き慣れない単語がバンバン出てきますので油断はできません。もちろんテストも入ってきます。
#5.1 構造を追加する#
改めて5章でやることについて

Webアプリケーションを作成するときは、アプリの見た目についても早いうちに把握しておいた方が良いでしょう。この章ではモックアップで完成形を紹介し、それを実装するための手順を見ていく形となります。

モックアップ(ワイヤーフレームとも呼ばれる)とは
実装後のアプリケーションの外観の草案。アプリ画面の完成図のようなもの。
あくまで草案なので動作はしない。

それではまずはトピックブランチの作成から

git checkout -b filling-in-layout

##5.1.1 ナビゲーション##

まずはサイトのレイアウトファイル「application.html.erb」にてHTMLのコードを追加して見た目を整えていきます
とりあえずテキストのコードをコピペして上から見ていきましょう

①headタグの内容から

<%= csrf_meta_tags %>

Webサイトへの攻撃から守ってくれる機能です

<%= csp_meta_tag %>

HTTPSを使用しやすくするための機能です

<%= stylesheet_link_tag    'application', media: 'all',
                               'data-turbolinks-track': 'reload' %>

これは以前見ましたね。あらゆるメディアタイプに対応できるようにする機能です。
ちなみに後半はハッシュということは4章で確認しましたが、「media」は「' '」がついていませんが、「'data-turbolinks-track'」には「' '」がついています。
これは「data-turbolinks-track」についている「-」がポイントで、これがつくとシンボルにすることができないので、「' '」で囲うことで無理やりハッシュロケット(=>)を省略した記法にしているということです。

<%= javascript_pack_tag 'application',
                               'data-turbolinks-track': 'reload' %>

JavaScriptに関する機能を盛り込んでいます。

<!--[if lt IE 9]>
   :
<![endif]-->

ここはRails関係ありません。
Microsoft Internet Explorer(IE)のバージョンが9より古い場合でもサイトを利用できるようにする機能です
ユーザーの中には古いバージョンを使い続けている人もいるでしょうしね。

②ページの上部の要素「header」タグ
ページに表示される一番上の部分ですね。
サイトのロゴを表示するheader、(divタグによる)いくつかの領域、ナビゲーションリンクのリストなどで構成されています。
が、上から見ていきましょう

<header class="navbar navbar-fixed-top navbar-inverse">

headerタグには、navbar、navbar-fixed-top、navbar-inverseという3つのCSSクラスがスペース区切りで与えられています
「navbar」と、3つついていますが、これは先ほど前置きでチョロっと出てきた「Bootstrap」を取り入れた時に何かが起こるみたいです。

<ul class="nav navbar-nav navbar-right">

少し下にあるこれもnavbarとついているので、「Bootstrap」に関係していそうです。

divタグによるいくつかの領域
divタグは一般的な表示領域を表し、要素を別々のパーツに分けるときに使われます

Railsヘルパーの「link_to」

<%= link_to "sample app", '#', id: "logo" %>

第1引数はリンクテキスト👉"sample app"
第2引数はURL👉'#'(これはダミーでとりあえず書いてるだけ。これではどこにも繋がりません!!)
第3引数はオプションハッシュ👉 id: "logo"(これは必須ではない)
・・・見た目では「sample app」が表示され、ポチると第2引数のURLに繋がります

ナビゲーションリンク

<nav>
  <ul class="nav navbar-nav navbar-right">
    <li><%= link_to "Home",   '#' %></li>
    <li><%= link_to "Help",   '#' %></li>
    <li><%= link_to "Log in", '#' %></li>
  </ul>

ナビゲーションリンクとかカッコつけてますけど、単なる箇条書きをリンクにしているだけですね。
後々、Homeを押すとHomeのビューが、Helpを押すとHelpのビューが出てきたりするようになるのでしょうきっと!

ちなみにですが、コンピュータ側からはこんな風に見えている見たいです

<nav>
  <ul class="nav navbar-nav navbar-right">
    <li><a href="#">Home</a></li>
    <li><a href="#">Help</a></li>
    <li><a href="#">Log in</a></li>
  </ul>
</nav>

ふーんて感じですね。HTMLですね。

メインコンテンツ用のdiv

<div class="container">
  <%= yield %>
</div>

まあ、**「yield」**ですね。原理としては結局分かったような分からないような感じですが。。。
この中にHomeとかHelpとかのテンプレート(いわゆるviews < static_pagesに入ってるやつね)が入るということでした。

次はstatic_pages < home.html.erb の中を整えていきます
まずはテキストをコピペします。相変わらずhtmlのコードの中にRuby混じってますなー
ここでもですが、divタグのCSSクラスjumbotronや、signupボタンのbtnクラス、btn-lgクラス、btn-primaryクラスはすべてBootstrapに関係してきます。。。あれもこれもBootstrapでどういう影響を及ぼしているのか楽しみなもんです

ここで新しいのはこれです

<%= link_to image_tag("rails.svg", alt: "Rails logo", width: "200px"),
                      "https://rubyonrails.org/" %>

先ほどまでは、「第1引数はリンクテキスト」だったので、表示された文字をポチるとリンクに繋がるようになっていましたが、今回は 「画像」です。
とても違和感ありますよね。。「link_toヘルパー」と「image_tagヘルパー」が並んでいるところが特に・・・覚えるしかないので覚えましょう

ちなみに、「image_tag」は「"rails.svg"」という名前の画像ファイルをどこから引っ張ってきているのでしょうか
ここです 👉 「app/assets/images/」
ですので、画像に「"rails.svg"」という名前をつけて、「app/assets/images/」にポイっと入れときましょう。後はRailsが勝手にやってくれてます。
##5.1.2 BootstrapとカスタムCSS##

さっきからやったらめったら出てきてた、**「Bootstrap」**を満を辞してRailsに取り込みます

Bootstrapについて
Twitterが作ってくれたデザインのパッケージセットです

どんな機能?
レイアウトをいい感じに見栄えよくするための必須アイテムです
洗練されたWebデザインとユーザーインターフェイス要素を簡単に導入できるCSSフレームワークをHTML5アプリケーションに追加できます。しかもレスポンシブデザインにしてくれます!レスポンシブデザインとは画面の大きさに合わせていい感じにしてくれるということです

使い方は?
「header class="navbar navbar-fixed-top navbar-inverse"」
「ul class="nav navbar-nav navbar-right"」
「div class="container"」
みたいにHTMLに**「Bootstrap特有の」**CSSのクラスを定義します

導入方法
gemを使って導入します
Gemfileに「bootstrap-sass」を追加します

gem 'bootstrap-sass', '3.4.1'

後はいつものbundle installです

$ bundle install

以上です。
え!?これだけ?
なんだか拍子抜けですね。

CSSファイルの管理について
チュートリアルではCSSを一つのファイルにまとめちゃうらしいので、とりあえずそれ用の「custom.scss」というファイルを作ります

$ touch app/assets/stylesheets/custom.scss

このコマンドで、app < assets < styleheets の階層に「cutom.scss」のファイルをポーンと作ることができます。便利ですね。
ここにCSSを書いて、レイアウトを整えていきます。。
その前に!!
ファイルをBootstrapに対応させる必要があります

app/assets/stylesheets/custom.scss
@import "bootstrap-sprockets";
@import "bootstrap";

さてさて、準備が整いましたので、サーバーをいったん閉じて起動しなおしてください。
するとあら不思議。
まだCSS何も書いてないのに、レイアウトがいい感じになりました。
これが「Bootstrap」の力です!
具体的には・・・ヘッダーの部分。「Sign up now!」のボタン。グレーの背景色。

あとはこれに、その他の部分にCSSを書き加えてレイアウトを整えていきます。
テキストコピペの時間です。。言われた通りにジャンジャン追加していきましょう。
何言ってるかよく分からない人はProgateのCSSコースでもやって思い出しましょう(投げやり)

webデザインについては余白、fontの色や大きさ、コントラストなどでページを見た時の印象がガラッと変わるため、知識があるに越したことはありません。
見た目が信頼に関わる要素にもなるため、ビジネス面でも大いに役立ちます。

##5.1.3 パーシャル(partial)##
パーシャルを使ってレイアウトのコードをスッキリさせる

今回はパーシャルを使って「app/views/layouts/application.html.erb」ファイルをスッキリさせていきます。
とりあえずテキストをコピペしてから見ていきましょうか
大分スッキリしましたが、原因はRailsヘルパーである**「render」**です

<%= render 'layouts/shim' %>

「render」は「app/views/layouts/_shim.html.erb」というファイルを見つけてきてビューにぶっ込みます。
と、いうことは、省略された部分は消えてなくなったわけではなくて、別のところに保管して、必要な時に「render」で引っ張って来れるようにしてるだけです

パーシャルはこのように必要な部分を分割して別保管して出力するための仕組みです!これを使うことで、レイアウトが必要以上にごちゃごちゃするのを防ぐことができます。
また、複数人で作業するときに、同じファイルを触ってたら更新する時に衝突が起きてしまう恐れがあります。パーシャルを使うことで、それぞれが別保管された場所で作業するので衝突の恐れもありません。

この、「別保管」をする際に注意点があります!
別保管をするファイルの頭に「 _ (アンダーバー)」をつけるのを忘れてはいけません
今回の例でいうと「_shim.html.erb」ということになります。

さて、今回は「render」が2箇所で使われているので、別保管ファイルを2つ作ります。
HTMLshim用の「_shim.html.erb」
ヘッダー用の「_header.html.erb」(ヘッダーパーシャル)
ここに作りましょう👉app < views < layouts

ついでに、フッター用の「_footer.html.erb」(フッターパーシャル)も作っときましょう。

今度はこれまでとは逆でパーシャル作成からレイアウト反映までの流れを見ていきましょう

  • layoutフォルダに「_footer.html.erb」(フッターパーシャル)を作る
  • レイアウト(application.html.erb)に「render」でフッターを入れる
  • custom.scssでフッターのレイアウトを整える

簡単ですがこんな流れになります。
#5.2 Sassとアセットパイプライン#
アセットパイプラインについての説明

簡単に言えばWeb画面上の色塗りを楽にする機能みたいです。
アセットパイプラインはJavaScriptやCSSのアセットを最小化 (minify: スペースや改行を詰めるなど) または圧縮して連結するための「フレームワーク」です。 CoffeeScriptやSass、ERBなど他の言語で記述されたアセットを作成する機能を追加することもできます。

とりあえずCSS、JavaScript、画像などの静的コンテンツの生産性と管理を「大幅に」強化することができるようになる機能とだけ覚えときましょう。
##5.2.1 アセットパイプライン##
アセットパイプラインについて詳しく説明

まずこれは、Railsに搭載されている機能です。(Bootstrapみたいに取り込んだりする必要はありません)
chromeなどのブラウザはCSSは読み込めるけど、CSSを拡張したSCSSで書いたようなコードはそのままでは読み込んでくれません。JavaScriptを拡張したものも同様です。
拡張したコードは読みやすいし開発する際に便利というメリットがあるもののコンピューターがそれを読み込むためには、毎回毎回拡張して書かれたコードを読み取れるように展開してあげないといけないという手間がかかるというデメリットもある。
この、デメリットの部分を解決してくれるのがアセットパイプラインです

アセットパイプラインは
①アセットディレクトリ、②マニフェストファイル、③プリプロセッサエンジンという、3つの主要な機能で動いていますので、一つずつ見ていくとしましょう

①アセットディレクトリ
静的ファイルを目的別に分類します
CSS、JavaScript、画像をそれぞれどこのフォルダで編集しましょう。ということを決めています。
②マニフェストファイル
①のフォルダ内でバラバラに分けたファイルを、1つのファイルにまとめる方法をRailsに指示します
スタイルシートフォルダに入った、たくさんの.scssファイルを整理します。
③プリプロセッサエンジン
指示に従ってサイトテンプレートとしてブラウザに配信できるように結合します。
「.scss」コンピューターにとって意味の分からないものを「.css」というわかる形に変えていく動きです。

①でバラして、③で解読して、②でまとめるてことかな。なんで順番前後しているのだろう・・・

チームで行う開発は作成するファイルごとに分割して進めた方が効率が良いし、コードの見た目もスッキリする
コンピューターは分割されてバラバラのデータよりも一つのファイルの方が読み込むためのスピードは早いし、ユーザーへのレスポンスも早くなる。
アセットパイプラインは開発する人間の都合とそれを読み込むコンピューターの都合を妥協することなくどちらもかなえてくれる画期的な仕組みということです。

ちなみに・・・Rails6.0バージョンではJavaScript系について、アセットパイプラインではなくて、「Webpacker」を使用しているみたいです。。やってることは同じですが、そこだけ切り離したみたいな感じですかね。

##5.2.2 素晴らしい構文を備たスタイルシート##
Sassについての説明
SassはCSSを拡張した言語であり、CSSと比べて多くの点が強化されます。
CSSと何が違うのかって、違うというよりかはCSSに新しい機能を追加したものです。
これまで「.scss」という拡張子が出てきましたが、これはCSSではなくてSCSSを指します。
ややこしいですがCSSファイルはSCSSファイルとして扱うことができます。

要は、Sassはスタイルシートを「簡潔」に「見やすく」してくれる機能です!

Sassの機能
①ネスト
スタイルシートにある共通のパターンの記述を短くすることができる

.center {
}
.center h1 {
}

こんな風に同じパターンが続いたらまとめることができます。

.center {
  h1 {
  }
}

別の例では

#logo {
}
#logo:hover {
}

このようにid属性の「#」ですと「&(アンパサンド)」が必要になります

#logo {
  &:hover {
  }
}

ネストを使って、同じクラスやidのやつはガンガン中に入れちゃいましょう

②変数
色の表現はCSSですと薄い灰色を「color: #777;」と記述します
「#777」を変数として定義することで、人間側からも見ても分かりやすい表現にすることができる
実例で示していきますと

h2 {
  color: #777;
}
footer {
  color: #777;
}

これを変数に入れていきます。「#777」を「light-gray」とするとします。

$light-gray: #777; # 「#777」を「light-gray」と定義

h2 {
  color: $light-gray;
}
footer {
  color: $light-gray;
}

「#777」と書かれているよりかは、断然見やすくなりますよね。
ここで再度登場するのが、「Bootstrap」です。
色などの、人間から見てぱっと見分かりにくいコンピューター用の表現を、変数で定義しています。
先ほど「bootstrap-sass」というgemを取り入れていますので、早速その変数を使うことができます。
実は先ほど「#777」を「light-gray」としましたが、「Bootstrap」はそれを「gray-light」と定義しているみたいです。

h2 {
  color: $gray-light;
}

footer {

  color: $gray-light;
}

これで先ほど自分で変数を定義した時と同じ内容で表示されます。

これまで作ってきたスタイルシートをネストや変数を使って書き換えてみましょう(コピペで)
変数については、「Bootstrap」で定義されてるものはそのまま使っていますし、「$gray-medium-light: #eaeaea;」のように、定義されていないものについては自分でカスタムして使っていますね。
※定義されたものにはどういうものがあるかはこちら👉「LESS変数一覧

③ミックスイン
テキストにはありませんでしたが、動画解説で紹介されていましたので載せときます。
CSSのデザインをパッケージ化して埋め込むことができます。
変数が一つのコードに名前をつけているのに対して、ミックスインはコードのかたまりに名前をつけているイメージです。よく使うスタイルがあったら、何度も同じことを書かなくてよくなります。
7章で使うことになるそうです。
#5.3 レイアウトのリンク#
link_toヘルパーの第2引数のURLについて

<%= link_to "about", '#' %>

5.1.1のナビゲーションで「link_toヘルパー」について上のコードで内容を確認しました。
今回は、その時とりあえずダミーで置いてた第2引数( '#' )をなんとかしていきましょう
ここには"Home"をクリックした時に、表示されるページのURLを入れます。
aboutページのURLは「/static_pages/about」です。
ですので

<%= link_to "about", '/static_pages/about' %>

としても繋がるのですが、ここでは別の記法を用いて**「about_path」**とします。

<%= link_to "about", 'about_path' %>

まさに読んで字の如く「aboutページへのパス」です。
こちらの記法を名前付きルートとし、ルーティングの際も使用していきます。

ページ名 URL 名前つきルート
Home / root_path
About /about about_path
Help /help help_path
Contact /contact contact_path
Sign up /signup signup_path
Log in /login login_path
##5.3.1 Contactページ##
Contactページの作成

ここでいったんさっきのルートパスの話は置いといて、
Contactページという新たなページを作っていきます
aboutページ同様にまずはテストから書いていきます

test/controllers/static_pages_controller_test.rb
  test "should get contact" do
    get static_pages_contact_url
    assert_response :success
    assert_select "title", "Contact | Ruby on Rails Tutorial Sample App"
  end

これは他のページのほぼコピペで良さそうですね。このままではもちろんテストは失敗するので、「ルーティング」「コントローラー」「ビュー」をいつもの流れで作っていきます。

真新しいことは何もないので、テキストを参考にそのまま書いていきましょう。
##5.3.2 RailsのルートURL##
名前付きルートを使えるようにする

少し飛びましたが、名前付きルートを実際に使えるようにするにはそのための設定が必要になります。
ルートとついているので、ルーティングです。
まずは「root」URLを定義するコードについて見ていきましょう

root 'static_pages#home'

これってたしか、デフォルト画面をhomeに指定するという意味合いで理解していたような気がします
それ以外にも実は名前付きルートを使えるようにする機能もあったみたいです

root_path -> '/'
root_url  -> 'https://www.example.com/'

ルートパスを '/' として、「https://www.example(あくまで例).com/」にアクセスできるということを表しています。
何気にURLに「/static_pages」をつけなくても良いURLに変わってますね

それでは「root」以外の他の部分もルートパスが使えるように整理していきましょう

get 'static_pages/help' => "static_pages#help"

この状態では名前付きルートパスは使えませんので形を変更します

get '/help', to: 'static_pages#help'

こうすることで名前付きルート(help_path)が使えるようになります

help_path -> '/help'
help_url  -> 'https://www.example.com/help'

「helpパス」で「https://www.example.com(これも例)/help」に接続できるようになります
「static_pages/help」としなくても「/help」とすることで「help」ページに接続できるようになってます。

この原理で他の「help」や「about」ページのルートも同じように変更しちゃいましょう

名前付きルートが使えるようになったので、テストの内容も変更が必要です

get static_pages_home_url

ここの部分に名前付きルートパスを当てはめて

get root_path

といった風に全体を書き換えましょう。

##5.3.3 名前付きルート##
レイアウトに名前付きルートをそれぞれ入れていく

レイアウトでダミーで入れていた「 "#" 」にかたっぱしから名前付きルートを入れていきましょう。
ちなみに名前付きルートは「' '」で囲む必要はないみたいです。
例えば「"#"」を「help_path」としていくといった感じです。

これでリンクからそれぞれのページに飛ぶことができるようになりました
##5.3.4 リンクのテスト##
「統合テスト」を使ってリンクが正常に動作するかテストする

ページにリンクを埋め込みましたので、そのリンクがちゃんと動いているかどうかをテストします
**「統合テスト(Integration Test)」**を行うとアプリケーションの端からは端までシュミレートしてテストすることができます。人間が指先確認しながらやる試験のようなものです。
統合テストは以下の手順で動きます

  1. ルートURL(Homeページ)にGETリクエストを送る.
  2. 正しいページテンプレートが描画されているかどうか確かめる.
  3. Home、Help、About、Contactの各ページへのリンクが正しく動くか確かめる.

ちなみに、「統合テスト」は今回初めてで、その機能自体は今の段階で搭載されていない状態です。
ですので、取り込みましょう。
取り込むのは・・・**「rails generage」**です!

$ rails generate integration_test site_layout

できたファイルにテストを書き込んでいきます

test/integration/site_layout_test.rb
  test "layout links" do
    get root_path ・・・ここが 1
    assert_template 'static_pages/home' ・・・ここが 2
    assert_select "a[href=?]", root_path, count: 2 ・・・これ以降 3
    assert_select "a[href=?]", help_path
    assert_select "a[href=?]", about_path
    assert_select "a[href=?]", contact_path
  end

assert_selectをこれまでとは違った使い方をしています
もともとは「この文字列は含まれていますかー」を確認する内容でしたが
今回は「このリンクは含まれますかー」を確認する内容となっています

assert_select "a[href=?]", about_path

「?」のところに「about_path」を置換しているみたいです。。。じゃ始めから"a[href=about_path]"じゃダメなのかな・・・て、疑問がわきそうですが・・・CSSの記法らしいです
これにより次のようなHTMLがあるかどうかをチェックすることができます

<a href="/about">...</a>

お次はこちらです

assert_select "a[href=?]", root_path, count: 2

大体同じですが、「count: 2」ってなんだよ・・・となりますが、ものすごく単純な話、「Home」ページに飛ぶリンクが2つあるので、2つカウントされているだけです。
ロゴの「SAMPLE APP」ってやつと、ヘッダーの「Home」のところね。

ちなみに今回みたいに「assert_select」はいろんな使い方があるみたいなので、テキストの使用例を眺めときましょう。

今回は作成した「test/integration/site_layout_test.rb」はこれまでと違う**「統合テスト」となります!
よって
ここの部分だけ**テストしたい場合はコードが若干異なりますので注意しましょう

$ rails test:integration # :integrationをつけるだけ

いつものように

$ rails test

を実施しますと、統合テストを含めた全てのテストが実行されます!
#5.4 ユーザーの登録: 最初のステップ#
ユーザー機能搭載について
これから、**「ユーザー登録」**の新機能を搭載します!
新しくページができるため、新しいURLができて、そのためのルーティングを作成します
それに伴ってコントローラーも作ります。と、言いましてもこの章では中身の詳しい機能は搭載しないので、真新しいことはありません。
##5.4.1 Usersコントローラー##
新機能搭載にはまずコントローラーから

まずはコントローラーから作成していきましょう
と、言いましても「rails genenate」すればいろいろできます

$ rails generate controller Users new

**「usersコントローラー」と「usersのビュー」フォルダと、「usersコントローラーのシンプルなテスト」**が作成されます
そして、しれっとルーターに「get 'users/new'」が追加されてますね
##5.4.2 ユーザー登録用URL##

ここも、これまでのおさらいの続きです
まずは、先ほど最後に確認したルーターから見ていきます

routes.rb
get 'users/new'

このように自動的に入力されているものについて2つ変更します
①URLを「new」ではなくて「signup」に変える
②名前付きパスに対応した内容に書き換える
その結果このようになりました

routes.rb
get '/signup', to: 'users#new'

名前付きパスになってURLが変わりましたのでテストの内容もそれに合わせて変更します
「get users_new_url」 → 「get signup_path」

次はsignupページへのリンクです
トップページにでかでかとある「Sign up now!」を「signup」ページに繋がるようにリンクを設定します
リンクに「signup_path」を入力しときましょう

最後に「signup」ページのビューを整えて完了です。。コピペしときましょう

#5.5 最後に#
いつものようにブランチに変更をマージしたり、Gitにプッシュしたり、Herokuにデプロイしましょう

$ git add -A
$ git commit -m "Finish layout and routes"
$ git checkout master
$ git merge filling-in-layout

Gitにpushする前にテストをするのを忘れずに

$ rails test
$ git push

最後にHerokuへデプロイです

$ git push heroku

#5章の要約をようやく作り終えての感想#
時間はかかりますが、要約を作りながら勉強を進めることや、解説動画の偉大さを身にしみて感じています。中途半端な理解のまま先に進むと本当に何も身につきません。
1周目では何も分からず、ただテキストのコードを丸写ししてただけでした。
一つ一つ「立ち止まって、自分の中に落とし込んで、内容を説明できる」。これですね。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?