Googleカスタム検索のカスタマイズ方法メモ

# はじめに
**（2015/06/16時点の情報です）**
Googleカスタム検索を導入する際に、地味に手間取ってしまったのでそれのメモです。

# 前提条件
- Googleアカウントをこちらで管理しておらず、既存のIDしか分からない
- 特に検索フォームはサイトに合わせたデザイン・レイアウトの調整が必要
- 検索結果はサイト内に表示させたい

# 一番手っ取り早い方法

見た目の調整がほぼ不要であれば、以下のコードをページに貼り付けるだけでOKです。
フォームをsubmitすると、そのページ上でオーバーレイとして検索結果が表示されます。
（ここでも表示を変更できる方法があるのかもしれませんが）

```search-area.html
<div id="search">
  <!--フォームの表示箇所-->
  <gcse:search></gcse:search>
</div>

<script>
  (function() {
    var cx = 'xxxxxxxx:yyyyyy';
    var gcse = document.createElement('script');
    gcse.type = 'text/javascript';
    gcse.async = true;
    gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
        '//www.google.com/cse/cse.js?cx=' + cx;
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(gcse, s);
  })();
</script>
```


# HTMLフォームに組み込む

上記やり方では、フォームや検索結果がjsで自動生成されるためCSSでの調整が手間です。
そこでHTMLフォームを作成し、組み込むことでカスタマイズの自由度を上げます。

**その際の流れ・ポイントは以下になります。**

- HTMLの検索フォームを作成し、必要な値をhiddenで渡す
- 検索結果ページを用意し、`action=""`へPATHを記述
  - 自サイト外でもよければ、`//google.com/cse`を指定
  - その場合は、別途IDなど必要な値を渡す
- Googleのロゴを配置しない場合は、input:text内に透かしマークを入れる必要がある
  - 透かしを自動的に入れるスクリプトは用意されている
  - formのIDは必須

## 検索フォーム側

```search-area.html
<div class="l-search">
  <form id="cse-search-box" action="/result.html">
    <input type="text" name="q" class="l-search__text" />
    <button class="l-search__btn"><img src="/common/img/ic_zoom.png" alt="検索"></button>
  </form>
</div>

<script type="text/javascript" src="//www.google.com/cse/brand?form=cse-search-box&lang=ja"></script><!-- 透かしマークを入れるスクリプト -->
```

あとはcssで好きなように装飾ができます。※透かしマークのスクリプトによって、elementに直接styleが設定されるので、!importantを使う場合もあるかもしれません


## 検索結果側（actionで指定したページ）

以下のようなコードを表示させたい箇所に埋め込みます。
正確には、スクリプトを読み込んだ上で、`<gcse:searchresults-only></gcse:searchresults-only>`で表示位置を調整します。

```result.html
<script>
  (function() {
    var cx = 'xxxxxxxx:yyyyyyyy';
    var gcse = document.createElement('script');
    gcse.type = 'text/javascript';
    gcse.async = true;
    gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
        '//cse.google.com/cse.js?cx=' + cx;
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(gcse, s);
  })();
</script>
<gcse:searchresults-only linkTarget="_self"></gcse:searchresults-only>
```


# 検索結果にiframeを使う？？

> Google カスタム検索では、iframe を使用してページのカスタム検索エンジンをホストすることはできなくなりました。

公式のヘルプにはこう書いてあるのですが、検索結果ページに記述するコードを以下のようにしても一応動作することは確認できました（iframeを自動生成して検索結果を表示するコード）。

``` result_iframe.html
<div id="cse-search-results"></div>
<script type="text/javascript">
  var googleSearchIframeName = "cse-search-results";
  var googleSearchFormName = "cse-search-box";
  var googleSearchFrameWidth = 680;
  var googleSearchDomain = "www.google.com";
  var googleSearchPath = "/cse";
</script>
<script type="text/javascript" src="//www.google.com/afsonline/show_afs_search.js"></script>
```

もしかしたら、そのうち動作しなくなったり、一部指定が効かなかったりするのかもしれません。あるいはiframeタグを直接記述することを指しており、こちらのようにjsでiframeを生成するものとは別なのかもしれません。詳しくは分かりませんでした。。。


# おわりに

今回手間取った理由は、どこまでがアカウントのコンパネ上で制御されるかがよく分からなかったためでした。検索結果をサイト内ではなく、//google.com/cseで行う場合とで渡せるパラメータに差があることにも気づきませんでした。

> action="//google.com/cse"とした場合、`<input type="hidden" name="cof" value="FORID:12" />`を渡すとデザインが変わったのが、自サイト内だと変更されなかった。など

もし何か間違っている、こうした方がもっとよい、というものがあればぜひご指摘ください。