中年プログラマーの息抜き

ブログをはじめました。気の向くままにプログラム関連ネタをメモしていきます。

Wordpress の記事を短く表示したい。語尾に三点リーダー(…)を付ける方法

f:id:tm-b:20161229140514p:plain

はじめに

ブログなどでタイトルや一覧画面のレイアウトを考えるとき、本文が長すぎたり画像が表示されてしまったりと、想定している枠内に文字が収まりきらなくなる場合があります。

PHPワードプレス)の投稿一覧画面と投稿内容画面との関係を考えていて投稿一覧画面にも簡単な説明文を表示したいことはありませんか? この場合、例えばカスタムフィールドなどを利用して、一覧表示文と投稿本文とをそれぞれで保存しておくのが簡単です。といっても面白くないので、今回は、投稿本文の中から100文字の一覧表示文を自動作成して、100文字を超えたところで語尾に三点リーダー(…)を付ける方法を紹介します。こうしておくと一覧表示レイアウトから簡単な説明が読み取れますし『あ、まだ続きがあるんだ…。』ということも伝わりますね。

まずは完成イメージ

今手伝っているフェスの準備でWordpressを使ってみました。(期間限定の紹介です)※レイアウトはデザイナーさんがきれいに仕上げてくれます。

onestead.xsrv.jp

目指すこと(実現したいこと)

PHPワードプレス)の投稿本文に設定した内容を一覧画面へ反映する

「テキストを含むタグ以外(img)などは除去する」

「文字数は上限(100文字)を設ける」

「文字数上限を超える場合、語尾に三点リーダーを付与する」

「XSERVER」環境(Wordpress)で動作する

PHPワードプレス)で語尾に三点リーダ

function.phpなどへ作成しておき表示用のPHPファイルから実行するだけです。

<?php echo(strimwidth_post_contents($post->post_content)); ?>

まとめ

ちょっとしたことですがヒューマンエラーを減らすことにもつながりますし、自動処理させるという視点は大切なのかなと感じます。REST化してJS経由から実行すればShopifyなどで活用するなど利用シーンはあるのかな。

DOMDocumentって何者?

ここで詳しく説明されてます。とても参考になります、ありがとうございます。

PHPでDOMを使ってHTMLをロード...

能古島フェスの紹介

W@F 福岡ワーケーションフェス2022

日本でもっともチルな島、能古島

メール受信からプログラムを実行し添付ファイル保存する

はじめに

レンタルサーバー(XSERVER)、メール受信をトリガーとし、プログラムを起動します。※Lambda Function的な...。
今回は、特定のアドレスがメール受信した時に、Perl5 のプログラム import_attachment.pl を実行する例を紹介します。

手順

トリガー設定(例)は、
 ⇒ Xserverレンタルサーバー|サーバーパネルから「メールの振り分け」をクリック
 ⇒ ドメイン選択画面から「設定対象のドメイン:選択する」をクリック
 ⇒ メール振り分け設定画面から「メール振り分け設定追加」をクリック

f:id:tm-b:20210906175202j:plain

・条件1(キーワード):特定のアドレス
・条件1(場所):あて先
・条件1(一致):内容を含む
・条件1(宛先):| /usr/bin/perl /home/(サーバID)/bin/import_attachment.pl
・処理方法(配送方法):転送

プログラム(import_attachment.pl)

/home/(サーバID)/bin/import_attachment.plを作りパーミッション「700」に設定すれば動くはず。

#!/usr/bin/perl

use strict;
use warnings;
use utf8;
use Time::HiRes "gettimeofday";
use MIME::Parser;

my @accepts = ('受け付けるメール送信者:メールアドレス');
my $output = '添付ファイル保存先のフルパス';
my $log = '実行ログファイルのフルパス';
my ($es, $ms) = gettimeofday();
my ($S, $M, $H, $d, $m, $y) = localtime;
($y, $m, $d, $H, $M, $S, $ms) = ($y + 1900, sprintf("%02d", ++$m), sprintf("%02d", $d), sprintf("%02d", $H), sprintf("%02d", $M), sprintf("%02d", $S), sprintf("%06d", $ms));

open(LOG, ">>$log") || die;
flock(LOG, 2) || die;
print LOG "\n[$y/$m/$d $H:$M:$S.$ms] START, ";

my $mp= new MIME::Parser;
$mp->output_to_core(1);
$mp->tmp_to_core(1);
$mp->tmp_recycling(1);
$mp->use_inner_files(1);

my $mail= $mp->parse(\*STDIN);
my @from = $mail->head->get('From') =~ /<(.+)>/;
print LOG " from=$from[0], ";

@from = grep { $_ eq $from[0] } @accepts;
if (scalar(@from) > 0 && $mail->is_multipart) {
    my $count = $mail->parts;
    for (my $i = 0; $i < $count; $i++) {
        my $entity = $mail->parts($i);

        my $mime = $entity->head->mime_type;
        print LOG " mime=$mime, ";

        my $name = "$output/$y$m$d$H$M$S$ms".sprintf("%04d", rand(1000));
        if ($mime eq "image/jpeg") {
            $name .= ".jpg"
        } elsif ($mime eq "application/pdf") {
            $name .= ".pdf"
        } else {
            next;
        }
        print LOG " name=$name ";

        my $body = $entity->bodyhandle;
        my $IN = $body->open("r") || next;
        my $data = $IN->getline();
        if (defined($data)) {
            print LOG " (save)";
            open(OUT, ">$name") || next;
            eval {
                do {
                    print OUT $data;
                } while (defined($data = $IN->getline()));
                close(OUT);
                chmod 0600, $name;
            };
            if (my $e = $@) {
                print LOG "$e, ";
            } else {
                print LOG ", ";
            }
        } else {
            print LOG " (skip), ";
        }
        $IN->close;
    }
    print LOG " END ";
} else {
    print LOG " IGNORE ";
}

flock(LOG, 8);
close(LOG);

1;

まとめ

プログラムが異常終了したときは、メール送信者にその内容が自動送信されるようでした。。自前でログを書きだしていくのは大変ですね。しみじみ
「perl5」、どうかなって思いつつ、楽なので書き進めましたが、流行的にも気が向いたら同じ処理を「python3」で、書き直したいなとさ。

PHP 自動定数(__FILE__、__DIR__)からシンボリックリンクのパスをそのまま利用

はじめに

5年くらい前、サーバ内にいくつかのWordpressをデプロイするときに、設定ファイルとデータベース以外はシンボリックリンクで扱えるように(毎回Wordpress一式をコピーしなくても量産できる)方法を調べたことがあったなと思い出したので、今更ながら思い出せる範囲でメモってみる。

tm-b.hatenablog.com

PHP言語の標準動作はこうですね。

シンボリックリンクを解決した後の・・・

www.php.net

ということでPHPソースをいじる

シンボリックリンクを解決する前の・・・

どこを触ったかなって思い出してますが、1つはここ・・だった気がします。(前回の記事でメモっとおけばよかった。。時間とともに忘れる)

php-7.1.0/Zend/zend_language_scanner.c

556行目付近

 

修正前

if (file_handle->opened_path) {
    compiled_filename = zend_string_copy(file_handle->opened_path);
} else {
    compiled_filename = zend_string_init(file_handle->filename, strlen(file_handle->filename), 0);
}

 

修正後

if (file_handle->opened_path) {
    file_handle->opened_path = zend_string_init(file_handle->filename, strlen(file_handle->filename), 0);
    compiled_filename = zend_string_copy(file_handle->opened_path);
} else {
    compiled_filename = zend_string_init(file_handle->filename, strlen(file_handle->filename), 0);
}

この流れでインストール

ソースを触るので、yumなどのパッケージマネージャ経由ではインストールできませんよね。当たり前ですが・・ PHPソースから「 configure make make install 」

まとめ

これ以外にも何か触った気がしますが、、また思い出したら追記かな

セキュリティ対策などPHP4位からシンボリックリンクのパスのそのままが取得できなくなったと記憶してますが、自分で使うクローズされたプログラムであれば、まあ言語仕様を拡張(変更)する的なことも面白かったですよ。良い思い出ですね。 気が向いたら当時のVMを起動してコンパイルしたときのソースでも確認してみようかと思ったのでした。(rootのパスワードなんだっけってなりそう(汗))

・・ 5年たった今では、ソースを追えないかもしれない(泣)・・