最新版のLazy Loadについて

いつの間にかjQueryのLazy Loadプラグインがバージョンアップされていました。

以前「スクロールするまで画像を読み込まない(はずの)Lazy Loadについて」の記事があり、Lazy Loadの使用を断念しましたが修正されたようです。(記事作成時のバージョンは 1.6.0)


Lazy Loadの公式サイトからダウンロードします。(http://www.appelsiini.net/projects/lazyload


公式サイトの上部にも書いてありますが、imgタグのsrc属性に代替画像を指定し、data-original属性に表示したい画像を指定します。

<img src="dummy.jpg" data-original="original.jpg" alt="..." />


そして以下をheadタグ内に記述します。

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.lazyload.js"></script>
<script type="text/javascript">
$(function(){ $("img").lazyload(); });
</script>


Firefoxプラグイン Live HTTP Headers などで画面を表示すると遅延読み込みが行われていることがわかると思います。
(スクロール後 data-original の画像がロードされるログが表示されます。)


ただしsrcが代替画像のためSEO的にはいまいちかもしれません。

CentOSにPostgreSQL9.1をソースからインストールする。

まずはコマンド用、データベース用のディレクトリを作成します。

mkdir /usr/local/pgsql9.1
mkdir /var/lib/pgsql9.1
mkdir /var/lib/pgsql9.1/data
chown postgres:postgres /usr/local/pgsql9.1/
chown -Rf postgres:postgres /var/lib/pgsql9.1/


次にソースをダウンロードします。
日本PostgreSQLの会からソースをダウンロードし、解凍します。

cd /usr/local/src/
wget ftp://ftp2.jp.postgresql.org/pub/postgresql/source/v9.1.0/postgresql-9.1.0.tar.gz
tar zxvf postgresql-9.1.0.tar.gz


パスとポート番号を指定してコンパイルを行います。

cd postgresql-9.1.0
./configure --prefix=/usr/local/pgsql9.1/ --with-pgport=5551
make
make install

※複数PostgreSQLをインストールする場合にはポート番号を指定してconfigureします。


もしconfigureで以下のようなエラーが発生した場合readline、zlibのインストールが必要です。

configure: error: readline library not found
If you have readline already installed, see config.log for details on the
failure. It is possible the compiler isn't looking in the proper directory.
Use --without-readline to disable readline support.


readlineはyumでインストールします。

yum install readline readline-devel


zlibは投稿日のバージョン1.2.3ではだめだったため、最新版の1.2.5をソースからインストールします。

cd /usr/local/src/
wget http://zlib.net/zlib-1.2.5.tar.gz
tar zcvf zlib-1.2.5.tar.gz

cd zlib-1.2.5
./conifigure
make
make install


次にデータベースの初期化を行います。

cd /usr/local/pgsql9.1/bin/
./initdb -D /var/lib/pgsql9.1/data --no-locale --encoding=UTF-8


次に設定ファイルの変更を行います。

vi /var/lib/pgsql9.1/data/postgresql.conf


postgresql.confは以下の内容を修正してください。

port=5551


起動スクリプトを作成します。

cp /usr/local/src/postgresql-9.1.0/contrib/start-scripts/linux /etc/rc.d/init.d/postgresql9.1


コピーした起動スクリプトの以下を修正します。

prefix=/usr/local/pgsql9.1

PGDATA=/var/lib/pgsql9.1/data


後は以前の記事の内容に従って設定すれば大丈夫です。

SSH、公開鍵を使用してリモートPCにアクセスする。

ローカルPCからリモートPCに対してアクセスを行います。

まずはアクセスするユーザでローカルPCにログインし、公開鍵を生成します。

以下はRSA公開鍵を生成します。

# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 root@local-pc1

保存パス、パスフレーズを求められますが入力せずに Enter キーを押下します。


そうすると root で実行した場合には以下のパスにRSA公開鍵が生成されます。

# cd /root/.ssh/
# ls -l
-rw-------  1 root root  887  6月 24 13:25 id_rsa
-rw-r--r--  1 root root  229  6月 24 13:25 id_rsa.pub


生成された公開鍵(id_rsa.pub)をリモートPCに転送します。

# scp /root/.ssh/id_rsa.pub root@remote-pc1:/root/


次にリモートPCにアクセスされるユーザでログインし、公開鍵を生成します。

# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 root@remote-pc1


リモートPCで生成した id_rsa.pub を authorized_keys というファイルに書き換え、ローカルPCから転送された id_rsa.pub の内容を追記します。

# cd /root/.ssh/
# mv id_rsa.pub authorized_keys
# cat ../id_rsa.pub >> authorized_keys


以上でローカルPCからリモートPCへパスワードを使用せずにアクセスすることができます。

# ssh root@remote-pc1


リモートPCが root でのログインを許可していない場合は PermitRootLogin の値を without-password に変更する必要があります。

# vi /etc/ssh/sshd-config
・
・
#PermitRootLogin yes
#PermitRootLogin no
PermitRootLogin without-password
・
・

jQueryを使用したアコーディオン

jQueryを使用したアコーディオンを作ります。

まずは jQueryをダウンロード します。

次にHTMLです。

accordion.html

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta http-equiv="Content-Script-Type" content="text/javascript" />
    <meta http-equiv="Content-Style-Type" content="text/css" />
    <title>アコーディオン</title>
    <style type="text/css">
    div.accordion {
        border: solid 1px #FF9999;
        background-color: #FFCCCC;
        cursor: pointer;
        margin-top: 5px;
    }
    div.accordion + div {
        border-style: solid;
        border-width: 0px 1px 1px 1px;
        border-color: #FF9999;
        padding: 5px;
    }
    div.accordion + div p {
        margin: 0px;
    }
    </style>
    <script type="text/javascript" src="js/jQuery/jquery-1.5.2.js"></script>
    <script type="text/javascript" src="js/jQuery/ui/jquery-ui-1.8.12.custom.js"></script>
    <script type="text/javascript">
    // <![CDATA[
        $(function() {
        	$('.accordion').click(function() {
        		  $(this).next().slideToggle();
        	}).next().hide();
        });
    // ]]>
    </script>
</head>
<body>
<div>
    <div class="accordion">アコーディオン1</div>
    <div><p>アコーディオン1です。アコーディオン1です。アコーディオン1です。</p></div>
    <div class="accordion">アコーディオン2</div>
    <div><p>アコーディオン2です。アコーディオン2です。アコーディオン2です。<br />アコーディオン2です。アコーディオン2です。アコーディオン2です。</p></div>
    <div class="accordion">アコーディオン3</div>
    <div><p>アコーディオン3です。アコーディオン3です。アコーディオン3です。<br />アコーディオン3です。アコーディオン3です。アコーディオン3です。<br />アコーディオン3です。アコーディオン3です。アコーディオン3です。</p></div>
</div>
</body>
</html>

携帯電話ページでのContent-Type

携帯電話でXHTMLを使用する場合にはまったこと。


HTMLファイルには以下のように設定
index.html

<?xml version="1.0" encoding="SJIS"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
<head>
  <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=SJIS" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <title>title</title>
</head>
<body style="background-color: red;color:blue;">
Hellow World!!
</body>
</html>

この状態で表示したが、携帯電話でスタイルが適用されない。


スタイルが適用されているサイトと見比べた結果、適用されているサイトのレスポンスヘッダーのContent-Typeはapplication/xhtml+xml、自分のレスポンスヘッダーのContent-Typeはtext/htmlとなっていた。


よってApache HTTPDAddTypeディレクティブ を追加

AddType application/xhtml+xml .html


特定のディレクトリ以下に設定する場合

<Directory "/usr/local/apache2/htdocs/mobile">
  AddType application/xhtml+xml .html
</Directory>


これでスタイルが適用されたHTMLが表示された。


AddTypeディレクティブはmod_mimeモジュールに含まれている。
以下のコマンドでmod_mimeが含まれているか確認できる。

/usr/local/apache2/bin/httpd -l | grep mod_mime
  mod_mime.c

mod_mime.cが表示されればAddTypeディレクティブを使用できる。

CentOSにApache HTTPDをインストールする。

まずは必要なバージョンのソースファイルをダウンロードし、解凍します。

cd /usr/local/src/

wget http://ftp.jaist.ac.jp/pub/apache//httpd/httpd-2.2.17.tar.gz

tar zxvf httpd-2.2.17.tar.gz


解凍したディレクトリに移動し、コンパイルを行います。

cd httpd-2.2.17/

./configure --prefix=/usr/local/httpd --enable-rewrite=shared
make
make install

上記は /usr/local/httpdディレクトリにインストールし、mod_rewrite モジュールもインストールします。


起動スクリプトを作成します。

cp /usr/local/src/httpd-2.2.17/build/rpm/httpd.init /etc/rc.d/init.d/httpd

vi /etc/rc.d/init.d/httpd


以下のように修正します。

#!/bin/bash
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# httpd        Startup script for the Apache Web Server
#
# chkconfig: 235 85 15
# description: The Apache HTTP Server is an efficient and extensible  \
#             server implementing the current HTTP standards.
# processname: httpd
# pidfile: /var/run/httpd/httpd.pid
# config: /usr/local/httpd/conf/httpd.conf
#
### BEGIN INIT INFO
# Provides: httpd
# Required-Start: $local_fs $remote_fs $network $named
# Required-Stop: $local_fs $remote_fs $network
# Should-Start: distcache
# Short-Description: start and stop Apache HTTP Server
# Description: The Apache HTTP Server is an extensible server
#  implementing the current HTTP standards.
### END INIT INFO

# Source function library.
. /etc/rc.d/init.d/functions

if [ -f /etc/sysconfig/httpd ]; then
        . /etc/sysconfig/httpd
fi

# Start httpd in the C locale by default.
HTTPD_LANG=${HTTPD_LANG-"C"}
# This will prevent initlog from swallowing up a pass-phrase prompt if
# mod_ssl needs a pass-phrase from the user.
INITLOG_ARGS=""

# Set HTTPD=/usr/sbin/httpd.worker in /etc/sysconfig/httpd to use a server
# with the thread-based "worker" MPM; BE WARNED that some modules may not
# work correctly with a thread-based MPM; notably PHP will refuse to start.

httpd=/usr/local/httpd/bin/httpd
prog=httpd
pidfile=/var/run/httpd/httpd.pid
lockfile=/var/lock/subsys/httpd
RETVAL=0

# check for 1.3 configuration
check13 () {
        CONFFILE=/usr/local/httpd/conf/httpd.conf
        GONE="(ServerType|BindAddress|Port|AddModule|ClearModuleList|"
        GONE="${GONE}AgentLog|RefererLog|RefererIgnore|FancyIndexing|"
        GONE="${GONE}AccessConfig|ResourceConfig)"
        if grep -Eiq "^[[:space:]]*($GONE)" $CONFFILE; then
                echo
                echo 1>&2 " Apache 1.3 configuration directives found"
                echo 1>&2 " please read @docdir@/migration.html"
                failure "Apache 1.3 config directives test"
                echo
                exit 1
        fi
}

# The semantics of these two functions differ from the way apachectl does
# things -- attempting to start while running is a failure, and shutdown
# when not running is also a failure.  So we just do it the way init scripts
# are expected to behave here.
start() {
        echo -n $"Starting $prog: "
        check13 || exit 1
#        LANG=$HTTPD_LANG daemon --pidfile=${pidfile} $httpd $OPTIONS
        daemon $httpd $OPTIONS
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && touch ${lockfile}
        return $RETVAL
}
stop() {
        echo -n $"Stopping $prog: "
#        killproc -p ${pidfile} $httpd
        killproc $httpd
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
}
reload() {
        echo -n $"Reloading $prog: "
        check13 || exit 1
#        killproc -p ${pidfile} $httpd -HUP
        killproc $httpd -HUP
        RETVAL=$?
        echo
}

# See how we were called.
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  status)
        if ! test -f ${pidfile}; then
            echo $prog is stopped
            RETVAL=3
        else
            status -p {$pidfile} $httpd
            RETVAL=$?
        fi
        ;;
  restart)
       stop
       start
       ;;
  condrestart)
        if test -f ${pidfile} && status -p ${pidfile} $httpd >&/dev/null; then
                stop
                start
        fi
        ;;
  reload)
        reload
        ;;
  configtest)
        LANG=$HTTPD_LANG $httpd $OPTIONS -t
        RETVAL=$?


動作確認を行います。

/etc/rc.d/init.d/httpd start


問題がなければ chkconfig に登録します。

chkconfig --add httpd
chkconfig httpd on

JAVAでスタイルシート付きXMLを生成する

スタイルシート付きXMLJavaでの生成の方法をメモ


出力したいXMLは以下

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="style.xsl"?>
<Sample>
  <items>
    <item>
      <title>タイトル0</title>
      <content>コンテンツ0</content>
    </item>
    <item>
      <title>タイトル1</title>
      <content>コンテンツ1</content>
    </item>
  </items>
</Sample>


XMLを生成するJavaです。
Sample.java

import java.io.OutputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.ProcessingInstruction;

public class Sample {
  public static void main(String[] args) {
    Sample sample = new Sample();

    try {
      Document document = sample.getDocument();

      // スタイルシート追加
      ProcessingInstruction pi = document.createProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" href=\"style.xsl\"");
      document.appendChild(pi);

      Element root = document.createElement("Sample");
      Element items = sample.getItems(document);

      root.appendChild(items);
      document.appendChild(root);

      sample.write(document, System.out);
    } catch( Exception e ) {
      e.printStackTrace();
    }
  }

  /**
   * 新しい {@link Document} インスタンスを取得します。<br>
   * 
   * @return {@link Document}
   * @throws ParserConfigurationException
   */
  public Document getDocument() throws ParserConfigurationException {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    return builder.newDocument();
  }

  /**
   * items要素を生成し、取得します。<br>
   * 
   * @param document {@link Document}
   * @return items要素
   */
  public Element getItems(Document document) {
    Element items = document.createElement("items");

    for( int i = 0; i < 2; i++ ) {
      Element item = document.createElement("item");
      Element title = document.createElement("title");
      title.appendChild(document.createTextNode("タイトル" + i));
      item.appendChild(title);
      Element content = document.createElement("content");
      content.appendChild(document.createTextNode("コンテンツ" + i));
      item.appendChild(content);
      items.appendChild(item);
    }

    return items;
  }

  /**
   * writerに生成したXMLを出力します。<br>
   * 
   * @param document {@link Document}
   * @param os {@link OutputStream}
   * @throws ParserConfigurationException
   * @throws TransformerException
   */
  public void write(Document document, OutputStream os) throws ParserConfigurationException, TransformerException {
    TransformerFactory factory = TransformerFactory.newInstance();
    Transformer transfor = factory.newTransformer();
    transfor.transform(new DOMSource(document), new StreamResult(os));
  }
}


標準出力されたXMLUTF-8で保存してブラウザで見るとXMLではなく、xslで記述したHTMLで見えます。


補足としてstyle.xslはこんな感じ

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:dc="http://purl.org/dc/elements/1.1/">
  <xsl:output method="html" encoding="UTF-8" />

  <xsl:template match="/">
    <xsl:apply-templates />
  </xsl:template>

  <xsl:template match="Sample">
    <html>
      <head>
        <meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8" />
        <title>スタイルシート付きXMLの生成</title>
      </head>
      <body>
        <h1>スタイルシート付きXMLの生成</h1>
        <xsl:apply-templates />
      </body>
    </html>
  </xsl:template>

  <xsl:template match="items">
    <xsl:for-each select="item">
      <div class="item">
        <h2><xsl:value-of select="title" /></h2>
        <p><xsl:value-of select="content" /></p>
      </div>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>