よしかわーるど

プログラミングで世界を変える

Rubyを学ぶ 3日目

Ruby を学ぶ 3 日目

前回の記事

Ruby を学ぶ 2 日目

論理演算子

&&||のような論理演算子を使うと、複数の条件を 1 つにまとめることができます。

条件1 && 条件2、条件 1 かつ条件 2

条件1 || 条件2、条件 1 または条件 2

メソッドの定義

Ruby は def を使ってメソッドを定義します。

def add(a, b)
  a + b
end
add(1, 2) #=> 3

Fizz Buzz 問題

ここでは、Fizz Buzz 問題を解く

以下の仕様になる。

  • 3 で割り切れる数値を引数に渡すと、"Fizz"を返す。
  • 5 で割り切れる数値を引数に渡すと、"Buzz"を返す。
  • 15 で割り切れる数値を引数に渡すと、”Fizz Buzz”を返す。
  • それ以外の数値はその数値を文字列に変えて返す。
def fizz_buzz(n)
  if n % 15 == 0
    'Fizz Buzz'
  elsif n % 3 == 0
    'Fizz'
  elsif n % 5 == 0
    'Buzz'
  else
    n.to_s
  end
end

Minitest の基本

require 'minitest/autorun'
require './lib/fizz_buzz'

class FizzBuzzTest < Minitest::Test
  def test_fizz_buzz
    assert_equal '1', fizz_buzz(1)
    assert_equal '2', fizz_buzz(2)
    assert_equal 'Fizz', fizz_buzz(3)
  end
end

Minitest 以外のテスティングフレームワーク

RSpec は独自の DSL を使ってテストコートを書きます。

require './lib/fizz_buzz'

RSpec.desctibe 'Fizz Buzz' do
    example 'fizz_buzz' do
        expect(fizz_buzz(1)).to eq '1'
        expect(fizz_buzz(2)).to eq '2'
        expect(fizz_buzz(3)).to eq 'Fizz'
    end
end

Ruby のテスティングフレームワークの中で最も歴史が古い、test-unit がある。

Ruby 本体のテストコードも test-unit で書かれています。

require 'test/unit'
require './lib/fizz_buzz'

class FizzBuzzTest < Test::Unit::TestCase
  def test_fizz_buzz
    assert_equal '1', fizz_buzz(1)
    assert_equal '2', fizz_buzz(2)
    assert_equal 'Fizz', fizz_buzz(3)
  end
end

次回の記事

Ruby を学ぶ 4 日目

Rubyを学ぶ 2日目

Ruby を学ぶ 2 日目

文字列の比較

'ruby' == 'ruby' #=> true
'ruby' == 'Ruby' #=> false
'ruby' != 'false' #=> true
'ruby' != 'ruby' #=> false

<, <=, >, >=を使って大小関係を比較することが出来る。

'a' < 'b' #=> true
'a' < 'A' #=> false
'a' > 'A' #=> true
'abc' > 'def' #=> true
'abc' < 'ab' #=> false
'abc' < 'abcd' #=> true
'あいうえお' < 'かきくけこ' #=> true

数値

# 正の整数
10
# 小数
1.5
# 負の整数
-3
# 負の小数
-4.75

数値には_を含めることが出来ます。_は無視されるので、大きな数の区切り文字として使うと便利。

1_000_000_000 #=> 1000000000
10 + 20 #=> 30
100 - 25 #=> 75
12 * 5 #=> 60
20 / 5 #=> 4

変数の手間に-を付けると、数値の正と負を反転できます。

n = 1
-n #=> -1

整数同士の割り算は整数になる点に注意してください。小数点以下は切り捨てられます。

1 / 2 #=> 0

小数点以下の値が必要な場合は。どちらかの値に小数点の.0 を付けます。

1.0 / 2 #=> 0.5
1 / 2.0 #=> 0.5

変数に整数が入っている場合は、to_fメソッドを呼ぶことで整数から小数に変更することができます。

n = 1
n.to_f     #=> 1.0
n.to_f / 2 #=> 0.5

%は割り算の余りを求める演算子です。

8 % 3 #=> 2

**はべき乗を求める演算子です。

2 ** 3 #=> 8

変数に格納された数値の増減

n = 1

# ++は構文として無効
# n++

# nを1増やす
n += 1

# nを1減らす
n -= 1

同様に*=, /=, **=も使える。

真偽値

# trueそのもの
true

# すべての数値
1
0
-1

# すべての文字列
'true'
'false'
''

nil も偽になる。実際のプログラミングではオブジェクトが nil かどうかで条件分岐させる機会が多いので、意外と便利。

データがあればそのデータを、データがなければ nil を返す find_data という架空のメソッドがあったとします。 データのある/なしで処理を変えたい場合、素直に nil かどうかをチェックすると次のようなコードになる。

data = find_data
if data != nil
  'データがあります'
else
  'データはありません'
end

Ruby の場合、false と nil 以外はすべて真なので、次のようなシンプルに書けます。

data = find_data
if data != nil
  'データがあります'
else
  'データはありません'
end

Rubyを学ぶ 1日目

Ruby の基礎を理解

Rubyオブジェクト指向言語

文字列や配列はもちろん、数値や nil を含めて、すべてがオブジェクト。

その証拠に数値や nil、true や false に対してもメソッドを呼び出すことが出来ます。

以下、確認したコード

irb(main):001:0> '1'.to_s
=> "1"
irb(main):002:0> 1.to_s
=> "1"
irb(main):003:0> nil.to_s
=> ""
irb(main):004:0> true.to_s
=> "true"
irb(main):005:0> false.to_s
=> "false"
irb(main):006:0> /\d+/.to_s
=> "(?-mix:\\d+)"

メソッド呼び出し

Ruby では次のような形式でオブジェクトのメソッドを呼び出すことができます。

オブジェクト.メソッド(引数 1, 引数 2, 引数 3)

引数の括弧は省略することも出来ます。

オブジェクト.メソッド 引数 1, 引数 2, 引数 3

引数がなければ、次のようにメソッドの名前だけを書くことも出来ます。

オブジェクト.メソッド

リテラル

ソースコードに直接埋め込む事ができる値のことをリテラルといいます。

# 数値
123

# 文字列
"Hello"

# 配列
[1, 2, 3]

# ハッシュ
{'japan' => 'yen', 'us' => 'dollar', 'india' => 'rupee'}

# 正規表現
/\d+-\d+/

変数(ローカル変数)の宣言と代入

変数は次のようにして宣言と代入を同時に行います。

変数名 = 式や値

# 変数を宣言する目的で変数名だけ書くと、エラーになる
x #=> NameError

x = nil

# 変数名はスネークケースで書く
special_price = 200

文字列

シングルクオートとダブルクオート

'これは文字列です。'
"これは文字列です。"

上のコード例ではどちらも文字列としての違いはありませんが、シングルクオートとダブルクオートでは挙動が異なる点があります。

文字列中に改行文字(\n)を埋め込みたい場合は、ダブルクオートで囲む必要があります。

# ダブルクオートで囲むと\nが改行文字として機能する
puts "こんにちは\nさようなら"
#=> こんにちは
#   さようなら

# シングルクオートで囲むと\nはただの文字列になる
puts 'こんにちは\nさようなら'
#=> こんにちは\nさようなら

ダブルクオートを使うと式展開が使えます。式展開を使う場合は#{ }の中に変数や式を書きます。

name = 'Alice'
puts "Hello, #{name}!" #=> Hello, Alice!

i = 10
puts "#{i}は16進数にすると#{i.to_s(16)}です" #=> 10は16進数にするとaです

Treasure2018 3日目 React

Treasure2018 3 日目

今日は React 入門

普段、JavaScript は書かないので、Treasure で圧倒的成長 💪

やったこと

React の気持ちを少しだけど理解した。

Flux, Redux などを触った。

redux-thunk に触れた。

React で TODO アプリを作成した。

TODO の追加が出来た 🎉🎉

JavaScript でテストコードを書いた!!

わからなかったところ

Redux がマジでわからなかった。

js, jsx 特有のコーディングが辛かった…

アロー関数の使い方がよくわからなかったので、JavaScript の気持ちになる。

dispatch ってなに?

  • ActionCreatot で生成された Action を Store に送る。
  • Store のインスタンスに dispatch を行うことで Store へ変更を伝える。

非同期処理の書き方がよくわからなかった。Promise の理解をせねば…

JavaScript Promise 本

今日のランチ

ラーメン屋 うさぎ さんの「冷やし担々麺」

f:id:yoshikawataiki:20190815235712j:plain

memo

技術の変化は螺旋

技術の差分を見出して変化の中に見を置こう

変化はチャンスでもある

jQuery の時代はとても長かった、そこで止まったままの人も少なくない。

React などはまだまだ歴が浅いので、若手にチャンスがあるのでは!

JavaScript の移り変わり

DOM ツリー全体を JacaScript で構築する

HTML も、場合によって CSS も JS でやる

サーバサイドは WebAPI のみ実装する

API があると、モバイルアプリにも落とし込めるので便利!

DOM 操作は極めて重い処理

DOM 操作をへらすことがテクニックだった

VirtualDOM

新しい情報がきたら、その情報をもとに新しい DOM をいちから作成する。

更新したら、再描画するのめっちゃすごい

React

Facebook 社が開発している。

Component

名前が異なるかもしれないが、2 種類あるらしい。

  • Stateful component
  • Stateless component

キャッシュをわざわざ消すのめんどくさいとき

cmd+shift+R

Redux

https://redux.js.org/

Redux は、React が扱う UI の state を管理する

  1. Single source of truth
  2. State is read-only
  3. Mutations are written as pure functions

Flux

flux について

Promise

Promise について

Treasure2018 2日目 Golang

Treasure2018 2 日目

今日は Golang 入門 2 日目

やったこと

簡単な Web アプリを Golang で書けることが出来た 🎉🎉

TODO アプリの拡張。

SQLGolang を繋げる作業。

SQL を叩いて Golang でパースすることが出来ました。

わからなかったところ

最後の TODO アプリの検索の仕方で手間取りました。

title と status で検索したかったけど、片方だけの検索しか出来なかった。

title と status の同時検索が出来なかった。

curl http://localhost:8080/api/todos/search?title=test\&completed=0

controller/task.goファイル

package controller

import (
    "encoding/json"
    "net/http"

    "github.com/voyagegroup/go-todo/model"

    "github.com/jmoiron/sqlx"
)

// Todo はTodoへのリクエストに関する制御をします
type Todo struct {
    DB *sqlx.DB
}

// GetはDBからユーザを取得して結果を返します
func (t *Todo) Get(w http.ResponseWriter, r *http.Request) error {
    todos, err := model.TodosAll(t.DB)
    if err != nil {
        return err
    }
    return JSON(w, 200, todos)
}

func (t *Todo) Put(w http.ResponseWriter, r *http.Request) error {
    var todo model.Todo
    if err := json.NewDecoder(r.Body).Decode(&todo); err != nil {
        return err
    }

    if err := TXHandler(t.DB, func(tx *sqlx.Tx) error {
        result, err := todo.Update(tx)
        if err != nil {
            return err
        }
        if err := tx.Commit(); err != nil {
            return err
        }
        todo.ID, err = result.LastInsertId()
        return err
    }); err != nil {
        return err
    }

    return JSON(w, http.StatusOK, todo)
}

// PostはタスクをDBに追加します
// todoをJSONとして受け取ることを想定しています。
func (t *Todo) Post(w http.ResponseWriter, r *http.Request) error {
    var todo model.Todo
    if err := json.NewDecoder(r.Body).Decode(&todo); err != nil {
        return err
    }

    if err := TXHandler(t.DB, func(tx *sqlx.Tx) error {
        result, err := todo.Insert(tx)
        if err != nil {
            return err
        }
        if err := tx.Commit(); err != nil {
            return err
        }
        todo.ID, err = result.LastInsertId()
        return err
    }); err != nil {
        return err
    }

    return JSON(w, http.StatusCreated, todo)
}

func (t *Todo) Delete(w http.ResponseWriter, r *http.Request) error {
    var todo model.Todo
    if err := json.NewDecoder(r.Body).Decode(&todo); err != nil {
        return err
    }

    if err := TXHandler(t.DB, func(tx *sqlx.Tx) error {
        _, err := todo.Delete(tx)
        if err != nil {
            return err
        }
        return tx.Commit()
    }); err != nil {
        return err
    }

    return JSON(w, http.StatusOK, todo)
}

func (t *Todo) Toggle(w http.ResponseWriter, r *http.Request) error {
    var todo model.Todo

    if err := json.NewDecoder(r.Body).Decode(&todo); err != nil {
        return err
    }

    if err := TXHandler(t.DB, func(tx *sqlx.Tx) error {
        _, err := todo.Toggle(tx)
        if err != nil {
            return err
        }
        return tx.Commit()
    }); err != nil {
        return err
    }

    return JSON(w, http.StatusOK, todo)
}

func (t *Todo) Search(w http.ResponseWriter, r *http.Request) error {
    title := r.URL.Query().Get("title")
    completed := r.URL.Query().Get("completed")

    todo, err := model.SearchByCompleted(t.DB, completed)
    if err != nil {
        return err
    }

    return JSON(w, http.StatusOK, todo)
}

model/task.go ファイル

package model

import (
    "database/sql"
    "time"

    "github.com/jmoiron/sqlx"
)

// Todoは管理するタスク
type Todo struct {
    ID        int64      `db:"todo_id" json:"id"`
    Title     string     `json:"title"`
    Completed bool       `json:"completed"`
    Created   *time.Time `json:"created"`
    Updated   *time.Time `json:"updated"`
}

func TodosAll(dbx *sqlx.DB) (todos []Todo, err error) {
    if err := dbx.Select(&todos, "select * from todos"); err != nil {
        return nil, err
    }
    return todos, nil
}

func TodoOne(dbx *sqlx.DB, id int64) (*Todo, error) {
    var todo Todo
    if err := dbx.Get(&todo, `
  select * from todos where todo_id = ?
  `, id); err != nil {
        return nil, err
    }
    return &todo, nil
}

// TodosToggleAllは全部のtoggleのステータスをトグルします
func TodosToggleAll(tx *sqlx.Tx, checked bool) (sql.Result, error) {
    stmt, err := tx.Prepare(`
  update todos set completed = ?
  `)
    if err != nil {
        return nil, err
    }
    defer stmt.Close()
    return stmt.Exec(checked)
}

func (t *Todo) Update(tx *sqlx.Tx) (sql.Result, error) {
    stmt, err := tx.Prepare(`
  update todos set title = ? where todo_id = ?
  `)
    if err != nil {
        return nil, err
    }
    defer stmt.Close()
    return stmt.Exec(t.Title, t.ID)
}

func (t *Todo) Insert(tx *sqlx.Tx) (sql.Result, error) {
    stmt, err := tx.Prepare(`
  insert into todos (title, completed)
  values(?, ?)
  `)
    if err != nil {
        return nil, err
    }
    defer stmt.Close()
    return stmt.Exec(t.Title, t.Completed)
}

// Toggle は指定されたタスクについて現在の状態と入れ替えます。
func (t *Todo) Toggle(tx *sqlx.Tx) (sql.Result, error) {
    stmt, err := tx.Prepare(`
  update todos set completed=?
  where todo_id=?
  `)
    if err != nil {
        return nil, err
    }
    defer stmt.Close()
    return stmt.Exec(!t.Completed, t.ID)
}

func (t *Todo) Delete(tx *sqlx.Tx) (sql.Result, error) {
    stmt, err := tx.Prepare(`delete from todos where todo_id = ?`)
    if err != nil {
        return nil, err
    }
    defer stmt.Close()
    return stmt.Exec(t.ID)
}

// TodosDeleteAllはすべてのタスクを消去します。
func TodosDeleteAll(tx *sqlx.Tx) (sql.Result, error) {
    stmt, err := tx.Prepare(`delete from todos where completed = 1`)
    if err != nil {
        return nil, err
    }
    defer stmt.Close()
    return stmt.Exec()
}

func SearchByTitle(dbx *sqlx.DB, title string) ([]*Todo, error) {
    var todos []*Todo

    if err := dbx.Select(&todos, "select * from todos where title = ?", title); err != nil {
        return nil, err
    }

    return todos, nil
}

func SearchByCompleted(dbx *sqlx.DB, completed string) ([]*Todo, error) {
    var todos []*Todo

    if err := dbx.Select(&todos, "select * from todos where completed = ?", completed); err != nil {
        return nil, err
    }

    return todos, nil
}

server.go に以下を追記

router.Handle("/api/todos/search", handler(todo.Search)).Methods("GET")

memo

SQL の使い方は以下の URL を参考にする。

https://github.com/go-sql-driver/mysql/wiki/Examples

http://go-database-sql.org/accessing.html

https://github.com/jmoiron/sqlx

https://github.com/variadico/scaneo

Treasure2018 1日目 Golang

Treasure2018 1 日目

今日は Golang 入門 1 日目

やったこと

隣の人が emacs を使っていたので、煽りました。

ちなみに、僕は vim 派です。

事前課題の発展問題のおさらいをしつつ、新しい問題を解きました。

$GOPATH を通そうという話。ディレクトリ構成は大事。

テストは大事。 後ろから殴られるぞ!

TDD 開発の理解を深めよう。

https://golang.org/pkg/testing/

隣の人と初めての共同作業(ペアプログラミングもどき)を行った ♡

curl の実装を行った。

複数のページからタイトルやディスクリプションを取得しました。

抽出したデータは JSON にパースしました。

わからなかったところ

スライスの使い方がよくわからなかった。

Go 言語: スライス(配列)の要素を取り出す方法

memo

suzuken さんのタイピングが早すぎる

ghq と peco は便利なので使おうな

コードレビューでおすすめのサイトはこちら - CodeReviewComments

Go言語入門 1日目

Go 言語 入門 1 日目

どうも、よしかわです。今日から Go 言語についてまとめていきたいと思います。

対象読者

  • Go 言語を学びたい人
  • Git が扱える人
  • Mac OS X を使っている人
  • 屈強な Windows ユーザー、Linux ユーザー

まとめ

Go 言語の環境構築からプログラムのコンパイル、実行をします。

また、パッケージについて紹介してきます。

参考文献

A Tour of Go

スターティング Go 言語

Go 言語入門

Golang ことはじめ - OthloBlog - オスロブログ -

環境構築

今回は Mac OS X にフォーカスして記事を作りたいと思います。

WindowsLinux をお使いの方はGetting Started - The Go Programming Language を参照してください.

Mac の方は, 以下のコマンドを実行.

brew install go

GOPATH 設定

.bash_profile などのファイルに追記します。

export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin

上記では、GOPATH にユーザーのホームディレクトリ直下の go ディレクトリを指定しています。

GOPATH は、import 文の解決に使われます。

Go1.8 から GOPATH の指定がない場合、\$HOME/go がデフォルトで設定されます。

ホームディレクトリ直下に go ディレクトリの作成を行います。

mkdir go

GOPATH は、 インポート文を解決するために使用されます。これは go/build パッケージによって実装され文書化されています。

現在のGOPATHを確認するには以下のコマンドを実行します.

go env GOPATH

カスタムGOPATHの設定はSettingGOPATH - golang/goを参照してください.

GOPATH以下のディレクトリ構成を知るのはとても良いことです.

GOPATH environment variableを参考にすると良いかもしれません.

GOPATH=/home/user/go

/home/user/go/
    src/
        foo/
            bar/               (go code in package bar)
                x.go
            quux/              (go code in package main)
                y.go
    bin/
        quux                   (installed command)
    pkg/
        linux_amd64/
            foo/
                bar.a          (installed package object)

コンパイルと実行

今回は「Hello, Go!!」を出力するプログラムのコンパイルと実行について説明していきます。

以下のソースコードを入力してください。

ファイル名「hello.go」という名前で保存します。

Go 言語のソースコードは「.go」の拡張子を用います。

package main

import "fmt"

func main() {
    fmt.Println("Hello, Go!!")
}

ソースコードの解説

ソースコードの内容について解説していきます。

  • 「package main」は、この hello.go がどのパッケージに所属しているかを決めています。
  • コンパイルしたプログラムは、main パッケージの main 関数から実行を始めます。
  • 「func main()」は main 関数の宣言です。この main 関数から実行を始めます。
  • 「import "fmt"」は、このファイル上で fmt パッケージを使用するための宣言です。宣言することによって fmt.Println 関数が使用できます。
  • 「fmt.Println("Hello, Go!!")」は、標準出力に「Hello, Go!!」を改行付きで出力します。

入力し終えたら hello.go ファイルをコンパイルします。

go build コマンド

ファイルを保存したディレクトリに移動して go build コマンドを実行します。

go build hello.go

今回は Mac OS X で開発するため、hello ファイルが作成されます。作成したファイルは以下のコマンドで実行出来ます。

./hello

「Hello, Go!!」と表示されたら成功です。

ようこそ、Go 言語の世界へ 🎉

go run コマンド

go run コマンドは、コンパイルと実行を続けて行います。

go run hello.go

go run コマンドを用いると、スクリプト言語のように開発することが出来ます。

パッケージについて

Go 言語では、「パッケージ」という仕組みがあります。

プログラムを分割することで機能を分離し、複雑な状態にしないようにしていきましょう。

同じパッケージ内にあるソースファイルは、同一のディレクトリに配置してください。

基本的に同一ディレクトリには複数のパッケージを配置できません。

パッケージの書き方

ソースファイルの構成は以下のとおりです。

  • 「package 文」 ソースファイルが所属するパッケージ
  • 「import 宣言」 他のパッケージをインポート
  • 「トップレベルの宣言」 変数や関数などの宣言

エクスポート

同一パッケージにある関数などは、それが他のソースファイルに記述したものであっても、特別なことをせず使用できます。

しかし、別のパッケージにある関数などは、エクスポートによって公開されていないと使用できません。

パッケージの「エクスポート」とは、トップレベルで宣言した関数などを別のパッケージに公開することです。

エクスポートされる対象は、トップレベルで宣言した対象のうち、 名前の先頭 1 文字が大文字 になっているものだけです。

// helloパッケージに所属
package hello

// 別パッケージから使用できる関数名
func Hello() {
    // ...
}

// 別パッケージから使用できない関数名
func hello() {
    // ...
}

インポート

パッケージの「インポート」とは、他のパッケージを読み込んで使用可能な状態にすることです。

エクスポートされた関数などは、そのパッケージをインポートすることで初めて使用できます。

パッケージのインポートは、「import 宣言」によって行います。

コメント

コメントは、ソースコードの説明する際などに用います。

1 行のコメント

// コメント

複数行のコメント

/から /まで

/*
    ここから
    ここまで
*/

おわりに

ここまで Go 言語の環境構築からプログラムのコンパイル、実行をしました。

また、パッケージについて紹介をしました。

次回は名前や、変数、定数、型などについて触れていきたいと思います。

CakePHP 入門 3日目

前回の記事

CakePHP 入門 2 日目

レイアウトの使用

今回は、レイアウトを使ったページの表示を行います。 index メソッドを修正します。

public function index(){
}

メソッドの中身がない状態にします。 そうすると、 http://localhost:8765/hello にレイアウトが反映されます。

レイアウトを作成

デフォルトをで使われているレイアウトは、どこにあるのか src/Template/Layout/default.ctp

スタイルシートの作成

webroot/css/cake.hello.css

body {
  background: #eee;
  color: #999;
  margin: 10px 0;
}

#header {
  font-size: 18pt;
  font-weight: bold;
  margin: 10px;
}
#content {
  background: #fff;
  color: #999;
  padding: 10px 25px 30px 25px;
  font-size: 14pt;
}
#footer {
  text-align: right;
  font-size: 12pt;
  margin: 10pt;
}
h1 {
  color: #aaa;
  font-size: 24pt;
  margin: 20pt 0pt 50pt 0pt;
}

レイアウトの作成

src/Template/Layout/hello.ctp

<!DOCTYPE html>
<html>
  <head>
    <?= $this->Html->charset();  ?>
    <title>
      <?= $this->fetch('title')  ?>
    </title>
    <?php
    echo $this->Html->css('cake.hello');
    echo $this->Html->script('cake.hello');
    echo $this->fetch('meta');
    echo $this->fetch('css');
    echo $this->fetch('script');
     ?>
  </head>
  <body>
    <div id="container">
      <div id="header">
        掲示板アプリ
      </div>
      <div id="content">
        <?= $this->fetch('content') ?>
      </div>
      <div id="footer">
        &copy; 2017 yoshikawataiki.net
      </div>
    </div>
  </body>
</html>

コントローラの修正

/src/Controller/HelloController.php

<?php
namespace App\Controller;

class HelloController extends AppController
{
  public function initialize(){
    $this->name = 'Hello';
    $this->viewBuilder()->autoLayout(true);
    $this->viewBuilder()->Layout('Hello');
  }

  public function index()
  {
  }
}
 ?>

レイアウトの流れ

HTML の中に、<?= ?>タグや<?php ?>が埋め込まれている。これらは、CakePHP で使用している各種のオブジェクトを利用したコードが使われている。

文字コードの設定とヘルパー

<?= $this->Html->charset(); ?> Html は「HtmlHelper」というクラスのインスタンスが収められている。これは「Html ヘルパー」という、ビューの入力を支援する機能を提供するためのもの。

<?= $this->fetch( ブロック名 )

fetch は、CakePHP のに保管されている「ブロック」と呼ばれる値を取り出す役割を果たします。ブロックというのは、表示するページで使われている各種の値やコンテンツなどのこと。title には、コントローラ側で$nameに設定された値がそのまま利用されています。

CSSJavaScript の設定

<?php
  echo $this->Html->css('cake.hello');
  echo $this->Html->script('cake.hello');
  echo $this->fetch('meta');
  echo $this->fetch('css');
  echo $this->fetch('script');
?>

fetch 以外に 2 種類のメソッドが使われています。 スタイルシートは、$thisの Html にある「css」というメソッドで設定します。 JavaScriptスクリプトファイルのロードは、$this->Html にある「script」というメソッドを使います。ここで利用したいスクリプトファイルの名前を引数に指定すると、「webroot」の「js」内からそのファイルを読み込んで使用します。script('cake.hello');ならば、「js」内にある「cake.hello.js」というファイルを読み込むためにタグを生成します。

残る 3 行は、「fetch」の呼び出しです。ここでは、「meta」「css」「script」というブロックを読込、出力しています。

エレメントの利用

エレメントは、レイアウトの内部にはめ込んで利用するテンプレートです。

まず、「Template」フォルダ内の「Element」フォルダの中に、「Hello」フォルダを作成します。

レイアウトを修正する

「Layout」内の hello.ctp を開き、書き換えます。

set による変数の設定

index メソッド内で、エレメントで利用する変数を用意し、レイアウトテンプレートに渡す用意をしています。テンプレート l に値を渡すためには、「set」というメソッドを用います。 $this->set( 変数名, 値);

set は、このように 2 つの引数を用意します。これで、テンプレート側に第 1 引数の名前で変数が用意され、そこに第 2 引数の値が代入されます。 エレメントの利用は、「コントローラからレイアウトへ」「レイアウトからエレメントへ」といった洗の受け渡しが非常に重要になります。コントローラの set メソッドと、レイアウトの element メソッドの使い方をしっかりと理解し、必要な値を必要なところへ適格に渡せるようにします。