初歩的知識
以下を参照した。
saruwakakun.com
- display:inlineは大きさ変えられない。display:blockかdisplay:inline-blockにする必要あり。aタグ, spanタグ。
- width:autoの決まり方 基本親要素まで広がる、%指定で親要素の何%かと言う決まり方になる(このときpadding, borderをつけているとはみ出るのでbox-sizing: border-box等をつける。)。
- min-width, max-widthで縮小に拡大に制限をつけられる。
- height:autoは中身の分の高さになる。%指定で親の高さがきまっていないときwidthなら親の親を辿ってブラウザの幅までいきつくがheightの場合は指定がきかなくなるので注意。
htmlを吐き出す4
何か形になってきた気が。とりあえず根本的にタグを定義してみた。
しかしdivとかを手で入れるようになってしまい面倒さは変わらないような気も。
import Data.List main = print (display html) type ClassName = String -- data DIV a = DIV ClassName a deriving Show -- data P a = P ClassName a deriving Show -- -- display:: DIV a -> String -- display (DIV name x) = name type TagName = String tag::TagName -> String -> String tag name txt = "<"++name++">" ++ txt ++ "</"++name++">" type AttributeName = String type AttributeString = String attr::AttributeName -> String -> AttributeString attr name txt = name ++ "=" ++ txt tagatt::TagName -> [AttributeString] -> String -> String tagatt name att txt = "<" ++ name ++ " " ++ attstr ++ ">" ++ txt ++ "</"++name++">" where attstr = intercalate "" att qua::String->String qua txt = "'" ++ txt ++ "'" data TAG = TAG TagName ClassName [ATTRIBUTE] [TAG] |Text String deriving Show data ATTRIBUTE = Attribute AttributeName String deriving Show class DISPLAY a where display:: a -> String instance DISPLAY TAG where display (TAG tagName className attributes tags) = tagatt tagName (map display ([Attribute "class" (qua className)]++attributes)) (intercalate "" (map display tags)) display (Text txt) = txt instance DISPLAY ATTRIBUTE where display (Attribute name txt) = attr name txt ----- html = TAG "html" "" [] htmlall htmlall = [header, body] header = TAG "header" "" [] [] body = TAG "body" "" [] [Text "hello"]
Styleタグを付けてみた。
import Data.List main = putStr (display html) type ClassName = String type TagName = String tag::TagName -> String -> String tag name txt = "\n<"++name++">\n" ++ txt ++ "</"++name++">\n" type AttributeName = String type AttributeString = String attr::AttributeName -> String -> AttributeString attr name txt = name ++ "=" ++ txt tagatt::TagName -> [AttributeString] -> String -> String tagatt name att txt = "\n<" ++ name ++ " " ++ attstr ++ ">\n" ++ txt ++ "</"++name++">\n" where attstr = intercalate "" att qua::String->String qua txt = "'" ++ txt ++ "'" data TAG = TAG TagName ClassName [ATTRIBUTE] [TAG] |Text String deriving Show data ATTRIBUTE = Attribute AttributeName String deriving Show type PropertyName = String data STYLE = STYLECLASS [ClassName] [PROPERTY] | STYLETAG TagName [PROPERTY] data PROPERTY = Property PropertyName String deriving Show class DISPLAY a where display:: a -> String instance DISPLAY TAG where display (TAG tagName className attributes tags) = tagatt tagName (map display ([Attribute "class" (qua className)]++attributes)) (intercalate "" (map display tags)) display (Text txt) = txt instance DISPLAY ATTRIBUTE where display (Attribute name txt) = attr name txt instance DISPLAY PROPERTY where display (Property name txt) = "\t" ++ name ++ ":" ++ txt ++ ";\n" instance DISPLAY STYLE where display (STYLECLASS classnames props) = intercalate "" (map (" ."++) classnames) ++ "{\n" ++ (intercalate "" (map display props)) ++ "\n}\n" display (STYLETAG tagname props) = tagname ++ "{\n" ++ (intercalate "" (map display props)) ++ "\n}\n" ----- html = TAG "html" "" [] htmlall htmlall = [header, body] header = TAG "header" "" [] [style] style = TAG "style" "" [] [Text (display css)] body = TAG "body" "hoge" [] [Text "hello"] css = STYLECLASS ["hoge"] [Property "background-color" "green"]
タグを幾つか定義してみた。これで大体がつくれるかもしれない。
import Data.List main = putStr (display html) type ClassName = String type TagName = String tag::TagName -> String -> String tag name txt = "\n<"++name++">\n" ++ txt ++ "</"++name++">\n" type AttributeName = String type AttributeString = String attr::AttributeName -> String -> AttributeString attr name txt = name ++ "=" ++ txt tagatt::TagName -> [AttributeString] -> String -> String tagatt name att txt = "\n<" ++ name ++ " " ++ attstr ++ ">\n" ++ txt ++ "</"++name++">\n" where attstr = intercalate "" att qua::String->String qua txt = "'" ++ txt ++ "'" data TAG = TAG TagName ClassName [ATTRIBUTE] [TAG] |Text String deriving Show data ATTRIBUTE = Attribute AttributeName String deriving Show type PropertyName = String data STYLE = STYLECLASS [ClassName] [PROPERTY] | STYLETAG TagName [PROPERTY] | STYLEEMPTY data PROPERTY = Property PropertyName String deriving Show class DISPLAY a where display:: a -> String instance DISPLAY TAG where display (TAG tagName className attributes tags) = tagatt tagName (map display ([Attribute "class" (qua className)]++attributes)) (intercalate "" (map display tags)) display (Text txt) = txt instance DISPLAY ATTRIBUTE where display (Attribute name txt) = attr name txt instance DISPLAY PROPERTY where display (Property name txt) = "\t" ++ name ++ ":" ++ txt ++ ";\n" instance DISPLAY STYLE where display (STYLECLASS classnames props) = intercalate "" (map (" ."++) classnames) ++ "{\n" ++ (intercalate "" (map display props)) ++ "\n}\n" display (STYLETAG tagname props) = tagname ++ "{\n" ++ (intercalate "" (map display props)) ++ "\n}\n" display (STYLEEMPTY) = "" ----- html = htmlcommon htmlall htmlcommon = _html "" [Attribute "lang" (qua "ja")] metacommon = _meta "" [Attribute "charset" (qua "UTF-8")] [] htmlall = [headtag "title" (style css) , body] _meta = TAG "meta" _html = TAG "html" _head = TAG "head" _body = TAG "body" _div = TAG "div" _p = TAG "p" _a href= \className -> TAG "a" className [Attribute "href" (qua href)] _title = TAG "title" style css = TAG "style" "" [] [Text (display css)] -- head headtag title style = _head "" [] [metacommon,style, (_title "" [] [Text title])] -- body body = _body "hoge" [] [_div "box" [] [Text "Hello", _a "https://yahoo.co.jp" "" [Text "link"]]] -- css css = STYLECLASS ["hoge"] [Property "background-color" "green"] -- template templatehtml title css bodytag = htmlcommon [headtag title (style css), bodytag] -- emptyhtml emptyhtml = templatehtml "title" STYLEEMPTY (_body "" [] [])
gistにのっけた。
html haskell · GitHub
htmlを吐き出す3
不要なデータ型を削除した少しスッキリしたが属性とかつけるとめんどくさいことになりそう。
import Data.List main = putStr (tag_doctype ++ html) tag_doctype = "<!DOCTYPE html>" html = string (HTML [header,body]) header = HEAD [String "OK!"] body = BODY htmlbody htmlbody = [DIV [P [String "Hello"]]] class TransString a where string::a -> String stringjoin::[a] -> String stringjoin list = intercalate "" (map string list) data Anchor = A { aURL::String, aLabel::String} instance TransString Anchor where string (A { aURL=u, aLabel=l}) = (tagatt "a" (attr "href" (qua u)) l) -- 色々なタグをタグでまとめた。 data TAG =HTML [TAG] |HEAD [TAG] |BODY [TAG] |TITLE [TAG] |DIV [TAG] |P [TAG] |String String instance TransString TAG where string (HTML tags) = tag "html" (stringjoin tags) string (HEAD tags) = tag "head" (stringjoin tags) string (BODY tags) = tag "body" (stringjoin tags) string (TITLE tags) = tag "title" (stringjoin tags) string (DIV tags) = tag "div" (stringjoin tags) string (P tags) = tag "p" (stringjoin tags) string (String txt) = txt tag::String -> String -> String tag name txt = "<"++name++">" ++ txt ++ "</"++name++">" attr::String -> String -> String attr name txt = name ++ "=" ++ txt tagatt::String -> String -> String->String tagatt name att txt = "<" ++ name ++ " " ++ att ++ ">" ++ txt ++ "</"++name++">" qua::String->String qua txt = "'" ++ txt ++ "'" trycode::(TransString a) => a -> String trycode x = string x
divにクラスを入れるようにしてみたがこれ以上やると複雑化しそうなので別の道を考える。。
import Data.List main = putStr (tag_doctype ++ html) tag_doctype = "<!DOCTYPE html>" html = string (HTML [header,body]) header = HEAD [String "OK!"] body = BODY htmlbody htmlbody = [DIV "di" [P [String "Hello"]]] class TransString a where string::a -> String stringjoin::[a] -> String stringjoin list = intercalate "" (map string list) data Anchor = A { aURL::String, aLabel::String} instance TransString Anchor where string (A { aURL=u, aLabel=l}) = (tagatt "a" (attr "href" (qua u)) l) -- 色々なタグをタグでまとめた。 type ClassName = String data TAG =HTML [TAG] |HEAD [TAG] |BODY [TAG] |TITLE [TAG] |DIV ClassName [TAG] |P [TAG] |String String instance TransString TAG where string (HTML tags) = tag "html" (stringjoin tags) string (HEAD tags) = tag "head" (stringjoin tags) string (BODY tags) = tag "body" (stringjoin tags) string (TITLE tags) = tag "title" (stringjoin tags) string (DIV cname tags) = tagatt "div" (attr "class" (qua cname)) (stringjoin tags) string (P tags) = tag "p" (stringjoin tags) string (String txt) = txt type TagName = String tag::TagName -> String -> String tag name txt = "<"++name++">" ++ txt ++ "</"++name++">" type AttributeName = String type AttributeString = String attr::AttributeName -> String -> AttributeString attr name txt = name ++ "=" ++ txt tagatt::TagName -> AttributeString -> String -> String tagatt name att txt = "<" ++ name ++ " " ++ att ++ ">" ++ txt ++ "</"++name++">" qua::String->String qua txt = "'" ++ txt ++ "'" trycode::(TransString a) => a -> String trycode x = string x
htmlを吐き出す2
html吐き出すコード、DivTag DIVとか書くのはおかしい。もっとまとまるはず。。
import Data.List main = putStr (tag_doctype ++ html) tag_doctype = "<!DOCTYPE html>" html = string (HTML [header,body]) header = HeadTag (HEAD (String "OK!")) body = BodyTag (BODY htmlbody) htmlbody = DivTag (DIV (PTag (P (String "Hello")))) class TransString a where string::a -> String stringjoin::[a] -> String stringjoin list = intercalate "" (map string list) data Anchor = A { aURL::String, aLabel::String} instance TransString Anchor where string (A { aURL=u, aLabel=l}) = (tagatt "a" (attr "href" (qua u)) l) -- 色々なタグをタグでまとめた。 data TAG =HTMLTag HTMLTAG |HeadTag HEADERTAG |BodyTag BODYTAG |TitleTag TITLETAG |DivTag DIVTAG |PTag PTAG |String String instance TransString TAG where string (HeadTag tag) = string tag string (BodyTag tag) = string tag string (TitleTag tag) = string tag string (DivTag tag) = string tag string (PTag tag) = string tag string (String txt) = txt data HTMLTAG = HTML { htmlText::[TAG]} instance TransString HTMLTAG where string (HTML { htmlText=tags}) = tag "html" (stringjoin tags) data HEADERTAG = HEAD { headTag::TAG} instance TransString HEADERTAG where string (HEAD { headTag=tag_}) = tag "head" (string tag_) data BODYTAG = BODY { bodyTag::TAG} instance TransString BODYTAG where string (BODY { bodyTag=tag_}) = tag "body" (string tag_) data TITLETAG = TITLE { titleTag::TAG} instance TransString TITLETAG where string (TITLE { titleTag=tag_}) = tag "title" (string tag_) data DIVTAG = DIV { divTag::TAG} instance TransString DIVTAG where string (DIV { divTag=tag_}) = tag "div" (string tag_) data PTAG = P { pTag::TAG} instance TransString PTAG where string (P {pTag=tag_}) = tag "p" (string tag_) tag::String -> String -> String tag name txt = "<"++name++">" ++ txt ++ "</"++name++">" attr::String -> String -> String attr name txt = name ++ "=" ++ txt tagatt::String -> String -> String->String tagatt name att txt = "<" ++ name ++ " " ++ att ++ ">" ++ txt ++ "</"++name++">" qua::String->String qua txt = "'" ++ txt ++ "'" trycode::(TransString a) => a -> String trycode x = string x
最初
processing.jsをダウンロードして配置する。
Processing.js
htmlを用意
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>title</title> <script src="./processing.js"></script> </head> <body> <canvas data-processing-sources="./proc.pde"></canvas> </body> </html>
proc.pdeファイルを用意してそこにprocessingの文法で描画すればOK。例として丸を多数動かす。
int MAX = 100; Target[] targets = new Target[MAX]; // 丸クラス // 準備はここに描く void setup() { size(1000, 1000); // サイズ指定 frameRate(20); // 動きのフレームレート指定 stroke(255, 0, 0); // 塗る色指定 // 丸の生成 for (int i=0;i<MAX;i++) { targets[i] = new Target(random(0,1000),random(0,1000),random(-3.0,3.0),random(-3.0,3.0)); } } // 描画処理はここに描く。フレームレートに応じて都度呼ばれる。 void draw() { // 消す background(0); // それぞれの丸に命令して描画させる。 for (int i=0;i<MAX;i++) { Target target = (Target)targets[i]; target.move(); target.draw(); } } // 丸 class Target { float x,y; float vx,vy; int id; // 初期化 Target(float xx, float yy, float vxx, float vyy) { x = xx; y = yy; vx = vxx; vy = vyy; } // 移動 void move() { x += vx; y += vy; if (x > 1000) { vx = abs(vx) * -1 } if (x < 0) { vx = abs(vx) } if (y > 1000) { vy = abs(vy) * -1 } if (y < 0) { vy = abs(vy) } } // 描画 void draw() { ellipse(x,y,10,10); } }
グラデーション
こちらのやり方にしたがってやってみた。
しかし値の調節にこつがいるのかもしれない。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <style> body { } #bg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; /* 背景グラデーションの作成 */ background: linear-gradient(to bottom, hsl(110, 80%, 40%), /* 色相80(360度中) 彩度 80% 輝度 40%*/ hsl(170, 80%, 60%), /* 色相140 */ hsl(230, 80%, 40%)); /* 色相200 */ background-size: 400% 400%; /* 画面からはみ出させることで変化をみせてる */ animation: AnimationName 10s ease infinite; } @keyframes AnimationName { 0% { background-position: 50% 0% } 50% { background-position: 50% 100% } 100% { background-position: 50% 0% } } </style> </head> <body> <div id = "bg"></div> </body> </html>
flexbox
flexboxを用いて、タイル表示をしてみる。以下を参考にした。
ics.media
HTMLはヘッダーにメニューとmainにタイルとしてdivを置いた。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>title</title> <link rel="stylesheet" type="text/css" href="sample.css"> </head> <body> <header> <img src="hoge.png" alt=""> <ul> <li><a href="">item1</a></li> <li><a href="">item2</a></li> <li><a href="">item2</a></li> </ul> </header> <main> <!-- カード的なUI --> <div class="animal"> <h1>うなぎ</h1> <img src="images/unagi.jpg" alt=""> <p>全身がなめらかな皮で覆われている魚である。</p> </div> <div class="animal"> <h1>イルカ</h1> <img src="images/iruka.jpg" alt=""> <p>魚のようだが哺乳類である。かしこい。</p> </div> <div class="animal"> <h1>いわし</h1> <img src="images/iwashi.jpg" alt=""> <p>最近高くなった。</p> </div> <div class="animal"> <h1>どじょう</h1> <img src="images/dojou.jpg" alt=""> <p>もはや見かけない</p> </div> </main> </body> </html>
レイアウトでflexを用いて均等に配置等を指定する。下記で主軸といっているのが横で交差軸と言ってるのが縦の設定と思えば良い。
/* flexには主軸と交差軸という概念 初期設定では主軸が左から右、交差軸が上から下 */ /* 主軸を均等割りに */ /* 交差軸を中央に */ header { display: flex; justify-content: space-between; align-items: center; } /* 主軸設定 flex-start,center,flex-end,space-between(両端は端につく),space-around(両端はボックスの半分) 交差軸設定 stretch(親と同じ高さ),flex-start,center,flex-end */ /* 交差軸を中央に */ ul { display: flex; justify-content: space-between; align-items: center; } main { display: flex; flex-wrap: wrap; /* 複数行配置 */ } main div.animal { width: calc(33.3% - 10px); margin: 5px; }
HTMLヘルパーでテーブルを作る
テーブルをガリガリと書く方法とHTMLヘルパーを使って各方法を2つ並べて書いてみた。
<h1> データ </h1> <table> <thead> <tr> <th>ID</th> <th>NAME</th> <th>TITLE</th> <th>CONTENT</th> </tr> </thead> <tbody> <?php foreach ($data as $obj): ?> <tr> <td> <?= $obj->id ?> </td> <td> <?= h($obj->name) ?></td> <td> <?= h($obj->title) ?></td> <td> <?= h($obj->content) ?></td> </tr> <?php endforeach; ?> </tbody> </table> <table> <thead> <tr> <th>ID</th> <th>NAME</th> <th>TITLE</th> <th>CONTENT</th> </tr> </thead> <?php $arr = $data->toArray();// 配列に取り出す for ($i = 0 ; $i < count($arr); $i++) { echo $this->Html->tableCells( $arr[$i]->toArray(), ['style' => 'background-color:#f0f0f0'], ['style' => 'font-weight:bold'], true); } ?> </table>
SQLiteの用意
CakePHPはデータベースやテーブルの設定を自分でする必要がある。大変面倒だがまずSQLiteでやってみることにする。
SQLiteのデータベースを作成する。
sqlite3起動
$ sqlite3 mydata sqlite> create table 'boards' ( 'id' integer primary key autoincrement, 'name' text not null, 'title' text, 'content' text);
tableができたことを確認
sqlite> .tables boards sqlite> .schema boards CREATE TABLE 'boards' ( 'id' integer primary key autoincrement, 'name' text not null, 'title' text, 'content' text);
ダミーレコードをいれておく。
sqlite> insert into 'boards' values (1,'name','test','test!'); sqlite> insert into 'boards' values (2,'name2','test2','test?');
確認
sqlite> select * from 'boards'; 1|name|test|test! 2|name2|test2|test?
データベースの設定 Config/app.php
そのDatasourcesという連想配列をいじる。
<?- // 略 'Datasources' => [ 'default' => [ 'className' => 'Cake\Database\Connection', 'driver' => 'Cake\Database\Driver\Mysql', // ここをSqliteに 'persistent' => false, 'host' => 'localhost', // 消す //'port' => 'non_standard_port_number', 'username' => 'my_app', // 消す 'password' => 'secret', // 消す 'database' => 'my_app', // ROOT . DS . 'db' . DS . 'mydata' とする(使うファイル名を、拡張子あるならそれをつけて)。DSはパス区切りを表す。 'encoding' => 'utf8', 'timezone' => 'UTC', 'flags' => [], 'cacheMetadata' => true, 'log' => false, 'quoteIdentifiers' => false, //'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'], 'url' => env('DATABASE_URL', null), ], // 略 ], ->
これでアプリ名にアクセス(例 ***/hoge)でwelcomeページをみて、下の方のdatabaseの項目が「CakePHP is able to connect to the database.」にチェックがついていることを確認する。
エンティティクラスの作成
src/Model/EntityにBoard.phpファイルを作成
<?php namespace App\Model\Entity; use Cake\ORM\Entity; class Board extends Entity { // 値の一括代入用の設定 id以外のすべては一括代入可能 protected $_accessible = [ '*' => true, 'id' => false ]; } ?>
テーブルクラスのファイルを作成
src/Model/TableにBoardsTable.phpファイルを作成
<?php namespace App\Model\Table; use Cake\ORM\Table; class BoardsTable extends Table { } ?>
コントローラの作成
<?php namespace App\Controller; class BoardsController extends AppController { public function index() { $data = $this->Boards->find('all'); // $dataはQueryクラス $this->set('data', $data); } } ?>
ビューの作成
src/Template内にBoardsフォルダを作成、index.ctpファイルを作る。
<h1> データ </h1> <table> <thead> <tr> <th>ID</th> <th>NAME</th> <th>TITLE</th> <th>CONTENT</th> </tr> </thead> <tbody> <?php foreach ($data as $obj): ?> <!-- $objはBoardエンティティクラス --> <tr> <td> <?= $obj->id ?> </td> <td> <?= h($obj->name) ?></td> <td> <?= h($obj->title) ?></td> <td> <?= h($obj->content) ?></td> </tr> <?php endforeach; ?> </tbody> </table>
これで表示まで一通りできた。
モデル = テーブル+エンティティ
フォームヘルパーを使う
テンプレートに次のように記述。
<p> ヘルパーを使ったフォームの送信</p> <p> <?= $result; ?> </p> <!-- FormHelperクラスを使ってformタグ生成 第1引数は値を保管するモデル名だが指定していないのでnull--> <?= $this->Form->create(null, ['type' => 'post', 'url' => ['controller' => 'Hello', 'action' => 'index']]) ?> <!-- inputタグ生成 フィールド名を指定、HelloFormのところはモデル名を指定していればそれを入れる --> <?= $this->Form->text("HelloForm.text1") ?> <!-- 送信ボタンタグ --> <?= $this->Form->submit("送信") ?> <!-- タグの終了 --> <?= $this->Form->end(); ?>
controller側
<?php namespace App\Controller; class HelloController extends AppController { // 略 public function index() { // 略 $result = ""; if ($this->request->isPost()) { $result = "<pre>送信情報<br/>"; foreach ($this->request->data['HelloForm'] as $key => $value) { $result .= $key . ' => ' . $value; } $result .= "</pre>"; } else { $result = "送信してください"; } $this->set("result", $result); } // 略 } ?>
フォーム
フォームをテンプレートに用意
<form method="get" action="/hello/sendForm"> <input type="text" name="text1" /> <inout type="submit" /> </form>
フォームを送った先
<h1>送信結果</h1> <p><?=$result ?></p>
ファイル名はsend_form.ctpとする。クラス、メソッド名はキャメル記法なのに対し、アンダースコア記法であることが注意するところ。
コントローラにhello/sendFormのアクションを書く
<?- class HelloController extends AppController { //略 public function sendForm() { $str = $this->request->query['text1']; //getで送ったものはquery連想配列に入っている。 $result="empty."; if ($str != "") { $result = "you type:" . $str; } $this->set("result", $result); } } ->
フォームを通してでなくても
snedForm?text1=hoge
でも送れる。
ただし、XSS攻撃回避策としてタグを無効化するエスケープ処理を入れる必要がある。それには
<?= $this->set("result", htmlspecialchars($result)); =>
とする。
省略記法として
<?= $this->set("result", h($result)); => でも良い。