静的HTMLページの中にLaravelを組み込む方法

### はじめに

* ふつうのページはデザイナーとかコーダーとかそういう別の人たちが静的なHTML/CSSでコーディングしている
* お問い合わせページのようなサーバーサイドの処理が必要なところだけはこれを読んでる人みたいなシステム担当がLaravelで開発している。
* Laravelのディレクトリ構造はご存知のとおりHTMLとCSSとかが分断されている
* 静的なHTMLは一つのディレクトリ内にCSSやJSが含まれている

ということを踏まえて、既に以下のようなディレクトリ構造が出来上がっていたとする

```
/static
  index.html
  css/
    static.css
  images/
    static.jpg
  js/
    static.js

/contact
  resources/
    views/
      index.blade.php
  public/
    css/
      contact.css
    images/
      contact.jpg
    js/
      contact.js
```

静的なほうはCSSや画像の読み込みが相対参照で、
動的なほうは読み込みが絶対参照で行われているだろうということが想像できると思う。

一番簡単なのは、viewsの中に静的なHTMLを、publicの中にCSSなどを入れること。こんな感じ。

```
  resources/
    views/
      static/
        index.blade.php
      contact/
        index.blade.php
  public/
    css/
      static.css
      contact.css
    images/
      static.jpg
      contact.jpg
    js/
      static.js
      contact.js
```

でも、それだとhrefや画像の読み込みの記述を全部正しく読むように修正する必要が出てくる。
それを誰がするか？ 当然Laravelのディレクトリ構造を知ってるシステム担当ですよね。きっつー

なので、Laravelのディレクトリ構造の中に、修正を要さない形で静的ファイルを配置したい。

### 新しいやり方 (2016/10/17追記)

もっと良い方法があったのでこちらを記載します。古いやり方は下のほうに書いてます。
どちらでもできますが、この新しいやり方のほうが良いと思います。ルーティングの手間も少ないし。

### 新しいやり方での実装

##### 静的なHTMLディレクトリを用意する

```
static/
  index.html
  css/
    static.css
  images/
    static.jpg
  js/
    static.js
```

こんなの。contactディレクトリは作らないでください

##### LaravelのプロジェクトをこのHTMLディレクトリとは別のところに作る

```
composer create-project laravel/laravel --prefer-dist project
```

```
static/
project/
  resources/
    views/
      contact/
        index.blade.php
  public/
    css/
      contact.css
    images/
      contact.jpg
    js/
      contact.js
```

こんな感じで。まあこれを見てるような人には説明不要だとは思いますが。

##### 静的HTMLディレクトリにcontactへのシンボリックリンクを貼る

もしドキュメントルートが /var/www/static/ の場合は次のような感じ

```
ln -s /var/www/project/public /var/www/static/contact
```

##### ルーティング

Laravel 5.2 の場合は、app/Http/routes.php、 5.3 の場合は、routes/web.php

```
Route::get('/', function() {
    return view('contact.index');
});
```

この '/' が、example.com/contact のことを示します。
viewは resources/views/contact/index.blade.php のことですね。
別に return view('index'); として、resources/views/index.blade.php を読み込んでもいいです。

これで期待通りの動作をするはず。おわり。

##### publicの参照先について

```
public/
  css/
    contact.css

--> /contact/css/contact.css または css/contact.css

/static/
  css/
    static.css

--> /css/static.css
```

##### 追記: formが動作しなくなった場合

新しいやり方だと、Viewは表示されますが、formが正しく飛ばないっていうつらみが起きました。

対処法は

```html
<form action="/contact" method="post">
↓
<form action="/contact/" method="post">
```

もしかすると私の環境だけかもしれませんが、.htaccessで、
URL末尾にスラッシュがなければスラッシュをつけるみたいな記述があり、リダイレクトしていたことが原因でした。
POSTの値はリダイレクト先までもっていくことができないため、次の画面に飛ぶ前に値が消失していたようです。

こちらでちょっと詳しく語ってます
https://teratail.com/questions/51670

Laravelを既存ディレクトリに無理やり組み込むより
Laravelのディレクトリ構造に合うようにHTML構造を作り直したほうが絶対いいよぉ。。それ言ったら本末転倒ですけどね

##### （新しいやり方）例外処理ページで静的な404ファイルを読み込ませる

非常にシンプルなやり方を思いつきました。
多分こっちのほうがいいと思います。こちらのやり方では404.blade.phpを作らないで下さい。
単にシンボリックリンクを貼るだけ

```
ln -s /var/www/static/errors/index.html /var/www/program/resources/views/errors/404.blade.php
```

##### （古いやり方）例外処理ページで静的な404ファイルを読み込ませる

resources/views/errors/404.blade.php になんか書いて
404ページを出してもいい、っていう場合はこの下は見なくていいです。

Laravelを組み込むと、Laravel配下とLaravel以外のディレクトリで二つ、404ページが必要になります。
example.com/static/a -> /var/www/static/errors/index.html が読み込まれる
example.com/contact/a -> /var/www/program/resources/views/errors/404.blade.php が読み込まれる

同じ内容のファイルが二重に存在するのはよろしくない、ので、Laravel配下でもHTMLの静的なファイルを読み込ませます。

```php:app/Exceptions/Handler.php
    public function render($request, Exception $exception)
    {
        if ($this->isHttpException($exception)) { // 404がきた時
            // return $this->renderHttpException($exception); // resources/views/errors/404.blade.php を表示する。（事前に作っておくこと）
            return redirect('/../errors/'); // /var/www/static/errors/index.html を表示する
        }

        if ( app() -> isLocal() || app() -> runningUnitTests() ) { // テスト環境またはローカル環境で500がきた時
            return parent::render($request, $exception); // Oopsのアレを表示する
        }
        else { // 本番環境で500がきた時
            return response() -> view("errors.500"); // resources/views/errors/500.blade.php を表示する。（事前に作っておくこと）
        }
    }
```

一度Laravelのシンボリックリンクの指定してある /var/www/static/contact に移動した後、
一つ上のディレクトリである /var/www/static に移動、その後に /var/www/static/errors/index.html を読みに行く、というイメージ。

なお、もしerrorsじゃなくて /var/www/error/index.html を読もうとしたのに表示されない場合、apacheの設定(/etc/httpd/conf/httpd.conf) でerrorにエイリアスがかかってないかを確認して下さい。
error は /var/home/error を読みに行く、みたいなことが書いてあると表示されません。私はこれに気付くのに丸一日かかりました。

### 古いやり方

HTMLやCSSファイルを全部丸ごとpublicフォルダにぶち込んでも動きます。こんな感じ

```
  resources/
    views/
      contact/
        index.blade.php
  public/
    static/
      index.html
      css/
        static.css
      images/
        static.jpg
      js/
        static.js
    css/
      contact.css
    images/
      contact.jpg
    js/
      contact.js
```

### 古いやり方での実装

上に書いたように、publicフォルダの中にデザイナーチームが作ったHTMLやらCSSファイル一式を丸ごとぶち込みます

そのあと、app/Http/route.phpで次のようにルーティングします。(Laravel ver.5.3の場合はroutes/web.php)

```
Route::get('/static', function() {
    return File::get(public_path() . 'static/index.html');
});

// トップページが静的ページの場合
Route::get('/', function() {
    return File::get(public_path() . '/index.html');
});
```

以上。結構こういう既存ページの一部にLaravelを組み込むってこと、よくありそうな気がするけど全然情報がない。つらみ。。