NO プログラム NO LIFE

ayanamiの備忘録

[Java]Struts2でValidatorをModelで定義する

Struts2でActionではなく、ModelでValidatorを定義する方法。

まずはAction。 com.opensymphony.xwork2.validator.annotations.VisitorFieldValidatorアノテーションを利用する。

1
2
3
4
5
6
private HogeDto hogeDto;

@VisitorFieldValidator
public void setHogeDto(HogeDto hogeDto) {
    this.hogeDto = hogeDto;
}

続いて、Model。

1
2
3
4
5
6
7
8
9
10
private String foo;

public String getFoo() {
    return this.foo;
}

@RequiredFieldValidator(key = "errors.required", messageParams = { "getText('foo')" })
public void setFoo(String foo) {
    this.foo = foo;
}

message.properties。

1
errors.required={0}は入力必須です。

最後にView。name属性をオブジェクト.プロパティの形式で定義する。

1
<s:textfield name="hogeDto.foo" />

[PHP]Yii + Ajaxで部分テンプレートを表示する

Yiiフレームワークを利用して、部分テンプレートを実装する方法。foobarに書き換えてみる。

まずはベースとなるbase.tpl

1
2
3
<script type="text/javascript" src="{Yii::app()->request->baseUrl}/js/ajax.js"></script>
<div id="button">fooをbarに書き換える</div>
<div id="replace-area">foo</div>

続いて、テンプレートとなるpart.tpl

1
2
<input id="base-url" type="hidden" value={$baseUrl}>
bar

テンプレートをレンダリングするajax_content.php

1
<?php echo $data; ?>

base.tplで読み込んでいるajax.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$(document).ready(function() {'use strict';

    $(document).on('click', '#button', function() {
        toBar();
    });

    function toBar() {
        return $.ajax({
            type: "GET",
            url: $("#base-url").val(),
            data: {
                ajaxRequest: "ajaxRequest"
            },
            complete: function(response) {
                var json = $.parseJSON(response.responseText);
                $("#replace-area").empty();
                if (json.data.content.length > 0) {
                    $("#replace-area").append(json.data.content);
                };
            }
        });
    };
});

最後にAjaxController.phpCController#renderPartial()を利用する。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public function actionIndex()
{
    // Ajaxのリクエストを判定。
    if (isset($_GET['ajaxRequest']))
    {
        // 部分テンプレートを文字列として取得。
        // 第3引数をtrueにすることで、文字列として取得できる。
        $content = $this->renderPartial('part', array(
                'baseUrl' => Yii::app()->createUrl('base'),
            ), true);

        $data = array(
                'content' => $content,
            );

        // アウトプットを文字列としてレンダリング。
        // 第4引数をtrueにすることで、文字列としてレンダリングできる。
        $this->renderPartial('ajax_content',
              CJSON::encode(array('data'=>$data)), false, true);
    }
}

[Passenger]複数アプリケーションを配置する

hogeアプリとfugaアプリを配置したい場合。 /etc/httpd/conf.d/直下に配置した任意の.confファイルを以下の様に記載。

1
2
3
4
5
6
7
8
<Location /hoge>
  PassengerAppRoot /opt/hoge
  RailsBaseURI /hoge
</Location>
<Location /fuga>
  PassengerAppRoot /opt/fuga
  RailsBaseURI /fuga
</Location>

[PHP]SmartyでYiiのWidgetを使う

YiiフレームワークのWidgetを普通に使う場合はこんな感じ。

1
2
3
4
5
6
7
8
9
10
11
12
<?php $this->widget('zii.widgets.jui.CJuiDatePicker', array(
    'model'=>$model,
    'attribute'=>'birthday',
    'language'=>'ja',
    'options'=>array(
        'dateFormat'=>'yy-mm-dd',
        'firstDay' => 1,
        'yearRange'=>'1900:+0',
        'changeYear'=>'true',
        'changeMonth'=>'true'
    ),
)); ?>

Smartyテンプレートエンジンを使った場合はこんな感じ。 arrayの書き方と、widgetの第3引数のtrueがポイント。

1
2
3
4
5
6
7
8
9
10
11
12
{$this->widget('zii.widgets.jui.CJuiDatePicker', [
    'model'=>$model,
    'attribute'=>'birthday',
    'language'=>'ja',
    'options'=>[
        'dateFormat'=>'yy-mm-dd',
        'firstDay' => 1,
        'yearRange'=>'1900:+0',
        'changeYear'=>'true',
        'changeMonth'=>'true'
    ]
], true)}

[Octopress]GitHubでブログを書く

GitHubからcloneしたOctopressのディレクトリ直下で、以下コマンドを実行。

1
bundle exec rake new_post['title']

octopress/source/_post/直下にyyyy-mm-dd-title.markdownが作成される。

1
2
3
4
5
layout: post
title: "title"
date: 2014-06-01 00:48:15 +0900
comments: true
categories: 

markdownで記事を生成し、以下のコマンドを実行。 実行後、http://localhost:4000/にアクセスして、内容を確認する。

1
bundle exec rake preview

内容がOKなら、以下のコマンドを実行。 実行後、http://username.github.ioにアクセス。

1
bundle exec rake gen_deploy

[Objective-C]UIControlのイベントハンドラに引数を渡す

Cocoaの[UIControl addTarget:action:forControlEvents:]ではactionに設定するセレクタに引数を渡すことができないので、 categoryblocksを利用して、自由に定義したコールバックを渡せるようにする。

ファイル名はUIControl+Blocksとする。まずはヘッダファイルを定義。

1
2
3
4
#import <UIKit/UIKit.h>
@interface UIControl(Blocks)
- (void)addTargetWithBlocks:(void (^)())blocks forControlEvents:(UIControlEvents)forControlEvents;
@end

次に実装ファイルを定義。category内ではインスタンス変数を保持できないので、関連参照を用いてblocksをストアする。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#import "UIControl+Blocks.h"
#import <objc/runtime.h>
@implementation UIControl(Blocks)
- (void)addTargetWithBlocks:(void (^)())blocks forControlEvents:(UIControlEvents)forControlEvents {
    objc_setAssociatedObject(self, @"key", blocks, OBJC_ASSOCIATION_COPY);
    [self addTarget:self action:@selector(callback:) forControlEvents:forControlEvents];
}
- (void)callback:(id)sender {
    void (^blocks)() = objc_getAssociatedObject(self, @"key");
    if (blocks) {
        blocks();
    }
}
@end

後は、任意のクラスでヘッダファイルをインポートすれば、[UIControl addTargetWithBlocks:forControlEvents:]が利用できる。

1
2
3
[btn addTargetWithBlocks:^{
    NSLog(@"%@", @"hoge");
} forControlEvents:UIControlEventTouchUpInside];

[Java]リストソート

listの要素がjava.lang.Comparableを実装している場合。

1
Collections.sort(list);

listの要素が以下の様なメンバを持つオブジェクトである場合。 面倒なので、getter、setterは省略。

1
2
3
4
public class Hoge {
    private int foo;
    private String bar;
}

barの昇順でソート。java.util.Comparator実装クラスが必要になる。 まずは、実装クラスを作って・・・

1
2
3
4
5
public class Fuga implements Comparator<Hoge> {
    public int compare(Hoge o1, Hoge o2) {
        return o1.getBar.compareTo(o2.getBar);
    }
}

比較処理を実行。

1
Collections.sort(list, new Fuga());

ちなみに、Objective-Cではこんな感じ

[Objective-C]配列ソート

要素がNSStringであるNSArrayのソート方法。

1
[array sortedArrayUsingSelector:@selector(compare:)];

要素が以下の様なプロパティを持つオブジェクトであるNSArrayのソート方法。

1
2
@property (nonatomic) NSUInteger hoge;
@property (nonatomic) NSString *fuga;

fugaの昇順でソート。

1
2
NSSortDescriptor *desc = [NSSortDescriptor sortDescriptorWithKey:@"fuga" ascending:YES];
[array sortedArrayUsingDescriptors:[NSArray arrayWithObject:desc]];

ちなみに、Javaではこんな感じ

Objective-Cの方が楽だなー。

[Java]数値判定

Javaにおける数値判定。 引数が、正規表現"^[0-9]+$"にマッチしているかを判定した結果を返す。

1
2
3
4
public static boolean isNumeric(String text) {
    Pattern pattern = Pattern.compile("^[0-9]+$");
    return pattern.matcher(text).find();
}

ちなみにObjective-Cではこんな感じ