2020-05-08

Chrome 拡張から Craft CMS へ GraphQLを使って投げるサンプルを作ってみた #craftcms

以前 Chrome 拡張で Craft CMS に投げるのを作った。

その時は Guest Entries を使ってやったのだけど、今回は GraphQL を使って試してみた。
Craft 3.5 ベータ以降であればこんな感じでできそう。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Axios Test</title>
  <script src="jquery.min.js"></script>
  <script src="axios.min.js"></script>
  <script src="popup.js"></script>
</head>
<body>
  <h1>Axios Test</h1>
  <form id="entryForm">
    <div class="form-group">
      <div class="form-check form-check-inline">
        <input class="form-check-input" type="radio" name="section" id="sectionBooks" value="1" checked>
        <label class="form-check-label" for="sectionBooks">Books</label>
      </div>
      <div class="form-check form-check-inline">
        <input class="form-check-input" type="radio" name="section" id="sectionArticle" value="2">
        <label class="form-check-label" for="sectionArticle">Article</label>
      </div>
    </div>
    <div class="form-group">
      <label for="c_title">Title</label>
      <input type="text" name="c_title" id="c_title" value="">
    </div>
    <div class="form-group">
      <label for="c_url">testtext</label>
      <input type="text" name="fields[testtext]" id="testtext" value="">
    </div>
    <button id="sendBtn" class="btn btn-primary">送信</button>
  </form>
</body>
</html>

popup.js

$(function(){
  var section;
  var c_section;
  function createEntry(title,testtext) {
    axios({
      url: 'http://example.com/api',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer hogehoge'
      },
      method: 'POST',
      data: {
        query: section,
        variables: {
          "title": title,
          "testtext": testtext
        }
      }
    })
    .then(function(response) {
      // success
      console.log(response);
      window.close();
    })
    .catch(function (error) {
      // error
      console.log(error);
    });
  }


  $('#sendBtn').on('click',function(){
    var c_title = $("#entryForm input[name='c_title']").val();
    var fields_testtext = $("#entryForm input[name='fields[testtext]']").val();
    c_section = $("#entryForm input[name='section']:checked").val();
    if(c_section == 1){
      section = `mutation($title:String,$testtext:String){
        save_test_test_Entry(
          authorId: 1,
          title: $title,
          testtext: $testtext
        ){
          id
          url
        }
      }`;
    }else{
      section = `mutation($title:String,$testtext:String){
        save_testtest_testtest_Entry(
          authorId: 1,
          title: $title,
          testtext: $testtext
        ){
          id
          url
        }
      }`;
    };
    createEntry(c_title,fields_testtext);
    return false;
  });

});

Craft CMS 側の設定で GraphQL のそれぞれのセクションに対するquery, mutationの設定はしておく。

ルートの設定で api エンドポイントの設定はしておく必要がある。
mutation をすることになるので、スキーマに対して設定したトークンを Authorization で渡すようにする。

manifest.json

{
  "name": "PostCraft",
  "version": "2.0.0",
  "manifest_version": 2,
  "browser_action": {
    "default_title": "PostCraft",
    "default_popup": "index.html"
  },
  "permissions": [
    "activeTab"
  ],
  "content_scripts": [
    {
      "matches": [
        "<all_urls>"
      ],
      "css": [],
      "js": [
        "jquery.min.js",
        "axios.min.js",
        "popup.js"
      ]
    }
  ]
}

unpacked な拡張として Chrome 側で取り込めばとりあえず問題なく動いた。

これまでのコードの継ぎはぎだったりで色々理解が足りていないところが多いなぁと思いつつ。
ラジオボタンの値に応じて投げるセクション変えてみたりしつつ。

勉強がてら Vue.js でやってみてもいいかも?とか思ったりもあったけど、引っかかった時にどこが原因かわからなくなりそうなので、とりあえずはこんな感じで。

Chrome 拡張にしておくのがベストかどうかはあるけれど、とりあえずCMSにデータをサクサク投げられるようにしておくことで色々使い勝手は広がるだろうからそういう周辺のもやっておかないとだろうなぁ。