git mergeやり直し手順メモ
マージし直すときの手順メモ。
いちおう今回はマージ先のブランチを残したい場合。で、この例だとgit reset でやり直せるけど今回やりたかったのはpushしたマージをやり直したかったのでこの形になった。
最初のマージ
$ git branch * dev1 dev2 $ git merge dev2 Auto-merging test CONFLICT (content): Merge conflict in test Automatic merge failed; fix conflicts and then commit the result. 〜コンフリクトを修正〜 $ git commit -m "マージするよ"
失敗に気づく・・・
マージやりなおす
$ git log --graph * commit xxxx3 |\ Merge: xxxx1 xxxx2 | | | | マージ | | | * commit xxxx2 | | | | dev2で追加 | | * | commit xxxx1 |/ | dev1で追加 | * # マージ前の状態で別ブランチを作る $ git checkout xxxx1 $ git branch * (HEAD detached at xxxx1) dev1 dev2 $ git checkout -b work # マージしなおす $ git merge dev2 Auto-merging test CONFLICT (content): Merge conflict in test Automatic merge failed; fix conflicts and then commit the result. 〜コンフリクトを修正〜 # workブランチをdev1ブランチに置き換える $ git merge -s ours dev1 $ git checkout dev1 $ git merge work
こんなやり方でいいのかわからないので、もっとよいやり方教えてください。以上です
無料で使えるSEOツールまとめメモ
最近、SEOツールを調べる機会があったのでメモしておく。っていっても使いこなせないのだが。。また調べることがありそうなのでそのときのためにメモしておく。
SEOチェキ
http://seocheki.net/
・発リンク数(外部リンク、内部リンク)
・Alexa traffic rank
・ドメイン取得年月
1日200回までの使用制限がある。
Moz
https://moz.com/researchtools/ose/
・ドメインオーソリティ(DOMAIN AUTHORITY)
・ページオーソリティ(PAGE AUTHORITY)
・ルートドメインへのリンク数(Root Domains)
・トータルリンク数(Total Links)
無料アカウントつくれば何回でも使えそう
Similar Web
・訪問者数(Total Visits)
・滞在時間(Avg Visit Duration)
・平均ページビュー(Page Per Visit)
・直帰率(Bounce Rate)
Pagespeed Insights
https://developers.google.com/speed/pagespeed/insights/?hl=ja
ページを解析して、修正が必要なところを指摘してくれる。PCとモバイルとそれぞれ対象。APIもある。
その他Google
site://example.com
link://example.com
Googleにインデックスされてるかの確認と被リンクされているかを確認できる。
他にもいろいろありそうだけどとりあえずこんな感じ。以上です。
【ionic】タブの中に入れ子でタブをいれる方法メモ - ion-tabs
はじめに
今回やりたかったのはこんな画面。
イマイチできるのか不安だったけど無事できた。
ionicは海外の情報が多くて「ionic tabs inside tabs」とか「ionic tab nested」ってみんな検索してるみたい。
イメージはこんなかんじ
アプリ特有?かわからないけど、タブごとにナビゲーションをつくってタブごとに遷移していくようなイメージ。
実装
app.js
angular.module('ionicApp', ['ionic']) .config(function($stateProvider, $urlRouterProvider) { $stateProvider // ベースとなるタブ .state('tabs', { url: "/tab", abstract: true, templateUrl: "templates/tabs.html" }) // ホーム .state('tabs.home', { url: "/home", views: { 'home-tab': { templateUrl: "templates/home.html" } } }) // ニュースタブの中のタブ .state('tabs.news', { url: "/news", abstract: true, views: { 'news-tab': { templateUrl: "templates/news.html" } } }) // 新着ニュース一覧 .state('tabs.news.new', { url: "/new", views: { 'news-page': { templateUrl: "templates/news-new.html" } } }) // お気に入りニュース一覧 .state('tabs.news.favorite', { url: "/favorite", views: { 'favorite-page': { templateUrl: "templates/news-favorite.html" } } }) // 新着ニュース詳細 .state('tabs.news.new-detail', { url: "/new-detail", views: { 'news-page': { templateUrl: "templates/news-detail.html" } } }) // お気に入りニュース詳細 .state('tabs.news.favorite-detail', { url: "/favorite-detail", views: { 'favorite-page': { templateUrl: "templates/news-detail.html" } } }) ; $urlRouterProvider.otherwise("/tab/home"); });
templates/tabs.html
<ion-tabs class="tabs-icon-top tabs-positive"> <ion-tab title="ホーム" icon="ion-home" href="#/tab/home"> <ion-nav-view name="home-tab"></ion-nav-view> </ion-tab> <ion-tab title="ニュース" icon="ion-document" href="#/tab/news/new"> <ion-nav-view name="news-tab"></ion-nav-view> </ion-tab> </ion-tabs>
templates/home.html
<ion-view title="ホーム"> <ion-content class="padding"> <p>ホーム</p> </ion-content> </ion-view>
templates/news.html
<ion-view title="ニュース"> <ion-tabs class="tabs-icon-top tabs-positive tabs-top"> <ion-tab title="新着" href="#/tab/news/new" icon="ion-ios-clock-outline"> <ion-nav-view name="news-page"></ion-nav-view> </ion-tab> <ion-tab title="お気に入り" href="#/tab/news/favorite" icon="ion-bookmark"> <ion-nav-view name="favorite-page"></ion-nav-view> </ion-tab> </ion-tabs> </ion-view>
templates/news-new.html
<ion-view title="新着ニュース一覧"> <ion-content class="padding has-tabs-top"> <p>新着ニュース一覧</p> <a href="#/tab/news/new-detail">詳細へ</a> </ion-content> </ion-view>
templates/news-favorite.html
<ion-view title="お気に入りニュース一覧"> <ion-content class="padding has-tabs-top"> <p>お気に入りニュース一覧</p> <a href="#/tab/news/favorite-detail">詳細へ</a> </ion-content> </ion-view>
templates/news-detail.html
<ion-view title="ニュース詳細"> <ion-content class="padding has-tabs-top"> <p>ニュース詳細</p> </ion-content> </ion-view>
ずらずら書いたけど以上です。
【angularjs】$http.postでのjson送信でoptions method not allowedを解決した時のメモ
やりたかったことは、localhostのサーバーで動いてるクライアントHTMLからサーバー上のAPIにPOSTでJSONを送るということでした。
なんかうまくいかなくて色々やってみたけど、結論からいうとangular側は以下のコードでいけました。
クライアント側
$http.post("/path/to/api",{ param1: "value1", param2: "value2" });
問題はサーバーサイドにありました。レスポンスヘッダーに以下を追記したらいけました。
Header set Access-Control-Allow-Origin "*" Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"
ちなみにfuelphpだと
Input::json(); // array("param1" => "value1", "param2" => "value2");
試したけどうまくいかなかったこと
// REQUEST METHODは解決するがFuelPHPでInput::jsonで取得できない $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; // REQUEST METHODは解決するがFuelPHPでInput::jsonで取得できない $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;application/json;charset=utf-8'; // REQUEST METHODがOPTIONSとなり、「405 Method Not Allowed」 $httpProvider.defaults.headers.post['Content-Type'] = 'application/json';
残念ながら丸半日以上でつぶれました。。。以上です
【fuelphp】Redisでロック・排他制御する方法メモ
APIの実装でクライアントからの2重送信対策にRedisを使ってみた。
MySQLでやろうとも思ったのだが負荷のことを考えるとRedisの方がいいのかなという判断。
$token = クライアントから送られるトークン $redis = Redis::forge(); if (1 === $redis->setnx($token, 1)) { // ロックに成功したら有効期限に1分をセット $redis->expireAt($token, time() + 60); } else { // ロックに失敗(同じキーが登録済み)なら処理中断 }
当初は$redist->get($key)で取得できたら、2重送信と判定していたのだがこれだと全く同タイミングだと正しく判定できない(排他制御できてない)。で、ググてみるとsetnxを使えとのことでした。動作確認したら期待通りの挙動となりました。以上です。
【javascript】iPhoneでpagehideが2回呼ばれたときの対応
今回やりたかったことは、ページから離れるとき(リンクとか)にその内容をサーバーに通知したいということ。pagehideで実装したのだが、なぜかiPhoneだとこれが2回呼ばれる現象だった(safari、chromeともに)。
以下のようなコードで確認したところ、2回送信されるのを確認。おそらく全く同時刻にランダム文字列が生成してるためかrandの部分が同じものが送信される。
var flg = true; window.addEventListener("pagehide", function() { if (flg) { flg = false; var rand = ランダム文字列を生成 var img = new Image(); img.src = "https://xxx/?rand=" + rand document.body.appendChild(img); } });
なのでやはりサーバー側でちゃんと対応しないとダメだねということで対応しました。以上です。
ionic(corodva)info.plistに追記して日本語化対応する - ios
アプリ内から別アプリを開いたら起動したアプリが全て英語だったのでその対応。というかionicで作ったアプリ自体が日本語化されてなかった。
xcodeでの開発の場合は、info.plistを直接いじればよいけどcorodva使ってる場合はxcode上で直接編集したものはbuild時に戻ってしまうのでcordovaで完結するようにする。
config.xmlへの記述でいけるのかと思ったのだがなぜかうまくいかなかったので別途プラグインを用意してplugin.xmlから追記する形でやってる人がいたのでそのやり方を真似させてもらった。
plugins-dev/plugin.xml
<?xml version="1.0" encoding="UTF-8"?> <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" id="plugin-localization-ios" version="0.1" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android"> <name>Localization Ios</name> <platform name="ios"> <config-file target="*-Info.plist" parent="CFBundleDevelopmentRegion"> <array> <string>Japanese</string> </array> </config-file> <config-file target="*-Info.plist" parent="CFBundleLocalizations"> <array> <string>ja</string> </array> </config-file> </platform> </plugin>
プラグインをプロジェクトへ組み込む
$ ionic plugin add plugins-dev/
platforms/ios/Sample/SampleCalendar-Info.plist
<key>CFBundleDevelopmentRegion</key> <array> <string>Japanese</string> </array> ・・・ <key>CFBundleLocalizations</key> <array> <string>ja</string> </array>
info.plistに追記されていればOK。
これで終わろうと思ったらプラグインありました。
https://github.com/enricodeleo/cordova-plugin-ios-localized-strings
$ ionic plugin add cordova-plugin-ios-localized-strings --variable MAIN_LANGUAGE=Japanese --variable ADDITIONAL_LANGUAGES=ja
これだけでいける。けど、指定したパラメータの情報ってどこにも保持されない気がするのでチーム開発だと厳しいのかな。。。以上です