[Concrete5]日本語URLが長すぎた[既知のバグらしい]

去年納品済みのお客さんから特定のページでエラーが出るとの連絡を受け、内容を確認したところ、以下のようなエラーメッセージが。

去年アップデートしてそのまま運用していたので、バージョンは5.6.2.1。

Warning: file_put_contents(/home/files/cache/pages/m/a/n/manual%2F%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4%25E4.cache) 
[function.file-put-contents]: failed to open stream: File name too long in /home/updates/concrete5.6.2.1.ja/concrete/core/libraries/page_cache/types/file.php on line 67

File name too long in
と書かれていたので、まぁファイル名が長いんでしょうなぁと思いつつも対策を探したけどイマイチよくわからなかったので素直にコンクリートファイブジャパンの佐々木さんに聞きました。

日本語URLの長さとキャッシュ

日本語でページURLが、ページキャッシュとして保存される際にURLエンコードされて上記の様なとんでもなく長いURLになってしまう為、エラーが表示されるという事だった。

対策

主な対策方法は4つ。

1.ページキャッシュをしない

日本語URLから作成されてバカみたいに長くなるキャッシュファイル名が問題なら元を断つ。
キャッシュを使用しなければ、エラーは出ない!(キリッ

2.日本語URLを使用しない

バカみたいに長くなるキャッシュファイル名が作成される元が、日本語のURLならそもそも日本語を使用しなければいいのでは。

3.エラーを表示しない

管理画面のデバッグ設定で、「来訪者からエラーを隠します。」にチェックをするとエラーが非表示になります。

うーん。根本的な解決にはならないかな…?

4.file.phpを書き換える

ページキャッシュを取っている記述をページIDにすれば解決と教えていただきました。

/concrete/core/libraries/page_cache/types/file.php 56行目〜70行目

public function set(Page $c, $content) {
		if (!is_dir(DIR_FILES_PAGE_CACHE)) {
			@mkdir(DIR_FILES_PAGE_CACHE);
			@touch(DIR_FILES_PAGE_CACHE . '/index.html');
		}

		$lifetime = $c->getCollectionFullPageCachingLifetimeValue();//←多分この辺を変えればいいのでは(無責任)
		$file = $this->getCacheFile($c);//←多分この辺を変えればいいのでは(無責任)
		if ($file) {
			$response = new PageCacheRecord($c, $content, $lifetime);
			if ($content) {
				file_put_contents($file, serialize($response));
			}
		}
	}

たぶん。というのも、coreの中をいじるのは怖くて実際にやってないので未検証なのです。

プログラムの知識が無くても簡単に使えるconcrete5ですが、こういう細かい部分になるとwordpressや他のオープンソースのツールに比べて参照元が少ないのが現状ですね…。

[Concrete5]concrete5+IE11でTinyMCE表示バグ[未解決]

はじまりは一本の電話

先日、ようやくの事XPのサポート終了でR.I.P IE6をしたばかりだというのに、今度はIE11。
勘弁してくださいよ。冗談抜きで。

お客さんから、「記事ブロック編集時にHTMLエディタを開いたら真っ白で何も出来なくなった!」というご連絡を頂きましたので、確認してみたところ、Firefox, Chrome, Safari, windows7+IE10では問題無し。
結構前に納品済みの案件でconcreteのバージョンは5.6.0.2。
新バージョンでのバグではなさそう。

IE11でのみ下記スクリーンショットのような状態が発生。

対策はまだ、ない

原因はまだ特定できておらず不明なのでとりあえず情報共有という形で投稿しておきます。

仮の対策として

ちなみに、HTMLエディタを開かなければ普通に記事ブロック編集ができたのですが、ちょっと不安なので、仮の対策としては以下の通り。

  • IE11を使わない。
  • IE11をどうしても使わなきゃならないなら、HTMLエディタを使わない。

以上2点。

お客さんが理解のある方なので、現状とりあえずはFirefoxかChromeで更新作業を行っていただくという方向で話をしていますが、会社の規定でIE11しか使っちゃダメってクライアントが居たら困りますねこれは…。

追記

菱川さんから貴重な情報いただいたので以下。

TinyMCEのバグレポート

https://www.tinymce.com/develop/bugtracker_view.php?id=6307
2013年9月の段階で確認されていたTinyMCEの既知のバグらしく。
つまり、concreteの問題ではない。

コメント欄見る限り、同様に表示されていない人がちらほらいました。
解決策としてmetaタグでIEを後方互換モードにしたらというコメントもあって参考になりました。が、果たしてそれで良いのだろうか…。

[Concrete5]良さげなアドオン[メモ]

良さげだったのでメモ程度に。


Best Concrete5 Add-Ons

スライダーのアドオン。
トランジションの豊富さと、カスタマイズ性に富んだアドオン。$15なので買ってみよう。


Slider Revolution Responsive Concrete5 Add-On

[Concrete5]エリア内にブロックがある時にだけ表示する[メモ]

実は、Concrete5公式活用ガイドブックの172ページに記載があるのですが、ちょっと気になった部分がありました。

エリアが空の時には何も表示しない要素を作る記述で以下の様なコードが載っていたのですが、

<?php
$a = new Area('Main');
if ($a->getTotalBlocksInArea($c) > 0) : ?>
<h1>この見出しはエリア内に何かブロックが配置されているときだけ表示されます</h1>
<?php
endif;
$a->display($c);
?>

これだと初めての編集時にエリアが表示されなかったんです。
編集時にエリアが表示されない = いつまでも編集できない。
つまりこのエリアはいつになっても表示される事がなくなってしまうのではないか。

で、編集モード時には表示されれば問題がないので、$c->isEditMode() を使って下記のようにしました。

<?php 
$a = new Area('Main');
if ($c->isEditMode() | $a->getTotalBlocksInArea($c) > 0){ ?>
<h1>この見出しはエリア内に何かブロックが配置されているときだけ表示されます</h1>
<?php
$a->display($c);
}
?>

これで安心。夜も眠れます。

[追記]

if文の閉じ括弧の部分について、ご指摘ありがとうございました。

下記の様なデザインを想定した場合に、ブロックが無い場合にはsectionごと非表示という方法は、ガイドブックに載っている方法では対応できませんでした。

<?php 
$a = new Area('Main');
if ($c->isEditMode() | $a->getTotalBlocksInArea($c) > 0){ ?>
<section>
<h1>この見出しはエリア内に何かブロックが配置されているときだけ表示されます</h1>
<?php
$a->display($c); // *1
?>
</section> *2
<?php } ?>

*1より前に閉じ括弧があると、*2の</section>タグが出力されてしまいます。
phpの問題というより、htmlのマークアップの問題ですね。
このような状況を想定しているため、先述のコードとなりました。

[Concrete5]ページURLを取得してテーマに表示する[メモ]

Concrete5の公式からいつの間にか消えてたのでメモ。
URLの取得なんて基本の基本すぎてわざわざ記事にしとく必要なんてないんだろうなぁ。

テーマファイルに以下の記述でページのURLが表示できました。

<?php
$nh = Loader::helper('navigation');
$URL = $nh->getCollectionURL($c);
echo $URL;
?>

WebデザイナーがConcrete5を使うことを躊躇う理由1

あまり参考にはならないかもしれませんが、Concrete5についていろいろな悩みを持っているという方が多いという話を聞いたので、自身の体験からデザイナーの悩みを払拭してみます

プログラムアレルギー

デザイナーが躊躇う第一の理由がプログラムです。

僕はweb業界で働くようになって、三年前にフリーランスになるまでプログラムは書いた事がありませんでした。
会社員時代にやって来た仕事は、基本的に設計書を書いて→デザインを起こして→htmlとcssでコーディングするまで。
システムの実装はプログラマにぶん投げていました。
僕もそうなのですが、はっきり言ってしまうとデザイナー職の人ってプログラム見るの嫌いなんですよ。アレルギー。
phpのソースファイル開いただけで「なんだそれ、わけわかんねー」って言って興味すら持たない人だっています。僕自身も昔そうでした。
もちろん、仕事上必要だから言語の基礎的な部分は理解してたつもりですが、ifとかechoとか本当に基礎の基礎、高校の授業で習うレベルの知識しかなかったんです。

そんな僕が出来ている理由をご紹介します。

実際にphpを新たに書く必要がほとんどない。

Concrete5は汎用性が高いCMSですが、基本的に普通にhtmlとcssを書いているのと同じ感覚でコーディングすれば特に問題がないです。
html+cssだったらWebデザイナーなら作業できますよね。それでいいんです。てかソレ以外にphpでいじる必要がある様なものは大体マーケットプレイスにアドオンがあります。

Concrete5の概念をシンプルに考えると、大きく分けて下記の二つに分類出来ます。

  1. テーマ(編集不可エリア)
  2. ブロック(編集可能エリア)

テーマは全体のデザインやレイアウトを決めるための要素です。
themesフォルダに入っています。htmlやcss、共通で使用する画像はここに置きます。
テーマのファイルは.phpですが、テーマ内にphpのループ処理や複雑な記述はありません。後述のブロック追加タグがあれば大丈夫。

ブロックは、CMSでは一般的に編集可能なエリアの事を指します。
テーマファイルの中にブロックの記述をするとその部分がCMS運用時にブラウザで編集可能になります。

<?php
$a = new Area('任意の英数');//場所毎に名前を変える
$a->display($c);
?>

実際にファイルを開いてみると、上記のブロック追加は最初から書いてあるのでhtmlのマークアップや、cssを変えるだけで組み込みできちゃいます。

ここまででphpを書く必要がほぼない事はご理解いただけましたでしょうか。

サイトを作るための要素が予め用意されているので自分で作る必要がない

静的なhtmlで30ページのサイトを作るとしたら、めんどくさいいくつかの作業があります。
例えばナビゲーションのリンクが切れてたり、パンクズはページ毎に設定しなきゃいけなかったり、共通部分のhtmlなんか毎回書いてられるかって話になると思うんですよ。で、手作業でやってると必ず間違えるんです。人間ですからしょうがないとしても、間違いの確認やら修正やらで余計な時間を取られるのって気持ちのいい事ではないですよね。
こんなのはたとえ話で実際にそんな案件ってもうあまり無いです。
むしろ静的htmlで30ページ作ったらconcrete5に組み込みするより高い見積もりにしないと割に合わないんじゃないかなぁ…。

で、予め用意されているものとして代表的なものが、以下。

  • スライドショー
  • オートナビゲーション
  • wysiwygエディタ
  • etc…

他にもたくさんあるけど、別の機会にご紹介します。
スライドショーは画像を選ぶだけで作れるし、オートナビはページさえ作れば各ページのサブページまでリスト構造化します。
wysiwygエディタは言わずもがな。エクセルからコピペすればそのままテーブルで入ったりしてとても便利。
これらは、特になにか設定をするわけでなく、デフォルトの機能です。

ブロックのカスタマイズもかんたん

「あぁ、ブロックから出力されるタグが<li>じゃなくて<p>だったらなぁ〜」と思った事はありませんか?

concrete5には「カスタムテンプレート」という機能があります。

これは、オートナビブロックやページリストブロックなどの出力される内容をちょっといじったりすることができます。

カスタムテンプレートはphpを知っていればより自由度の高い変更ができますが、僕は特に必要としていません。敢えてphpを書いていると言えば、ページタイトルを出力しているタグをコピペしたり、リンクをコピペしたり、基本的にコピペで出来てしまうんですよ。

 

ここまでで、プログラムについて細かく説明せずに書きましたが、本当にこの程度の知識で汎用性の高いCMS構築が出来てしまいます。

僕が簡単に扱える上に、お客さんからはこんなに使いやすいCMSは初めてですよ!とお喜びの声が聞けてwin-winの関係が築ける事間違いなし!!

concrete5 公式活用ガイドブック発売おめでとうございます!

※本の宣伝です。でも↓のamazonアフィで買ってくれると僕が嬉しいです。

2014/2/14に、ついに発売!
関係者の皆さん、おめでとうございます。そして、ありがとうございます!!
二年くらい前からずっとconcrete5の本が欲しかったのですが、日本語版がなくて困っておりました。
なんとkindle版もあるんですよ!これは嬉しい!!

書籍版

kindle版

そもそもconcrete5とはなんぞやって所から始まって、一通りの使い方のガイドブックです。

今忙しすぎてまだちゃんと読めてないんで、俺…この仕事が終わったら読むんだ…。

[Concrete5]オートナビにページの説明文を表示[メモ]

Concrete5、すごく便利です。
ただ一点、日本語のドキュメントというか、まだユーザが少ないのでwordpressみたいにググればすぐにヒットするような状況ではなくて、一つ一つ手探りでやるんですが、それでもダメでいつもSさんに頼っている次第でございます。

ページリストでやれば説明文は簡単に出せる、でも。

ページリストブロック

Concrete5のページリストブロックには、デフォルトで個別のページの説明文を表示する記述がされているので、ブロック設置時点で表示非表示はワンクリックで出来てしまいます。すげー。

そう、ページリストを使えば全く問題なくページのリンクリストと説明文を表示出来てしまうのですが、ページリストはデフォルトでは階層構造が出せないんです。

↓こんなマークアップがしたいのに。

<ul>
  <li><a href="oya">親ページ</a>
    <ul>
      <li><a href="ko">子ページ</a>
      <ul>
        <li><a href="mago">孫ページ</a>
      </ul></li>
    </ul></li>
</ul>

ページリストだと「親ページ > 子ページ > 孫ページ」と言った階層順に上記のようにマークアップしつつ一覧にする事ができない。
実際に出てくるマークアップは、↓のようになってしまいます。
<ul>
<li><a href="oya">親ページ</a></li>
<li><a href="ko">子ページ</a></li>
<li><a href="mago">孫ページ</a></li>
</ul>

全部並列になってしまう。
ページリストで階層を出したい場合は、カスタムテンプレートをいじる必要があります。

じゃあ、オートナビを使いましょう

オートナビ

階層構造をマークアップしたいのであれば、ページリストのカスタマイズをするより、オートナビを使用すれば何も考えなくても勝手に階層順にしてくれます。

うほっ!超らくちん!

と最初わたしは思いましたが、今回の案件で、お客さんの要望としては、「最下層にあるページの説明をリストに追加したい。」ということですので、上記のマークアップの例で言うと、下記の3点が大きな要件でした。

  1. 孫ページに説明文を表示
  2. 孫ページに説明文が入力されていない場合は非表示
  3. 親と子ページには説明文を表示しない

オートナビに説明文を表示する機能はデフォルトでついていないので、どうにかしてデータを引っ張ってこないといけないのです。

さて、どうしたもんか。

やっぱりカスタムテンプレートは使わないといけないのであった。

オートナビのデフォルトテンプレートは以下のような記述になっています。

echo '<ul class="nav">'; //opens the top-level menu
foreach ($navItems as $ni) {
	echo '<li class="' . $ni->classes . '">'; //opens a nav item
	echo '<a href="' . $ni->url . '" target="' . $ni->target . '" class="' . $ni->classes . '">' . $ni->name . '</a>';
	if ($ni->hasSubmenu) {
		echo '<ul>'; //opens a dropdown sub-menu
	} else {
		echo '</li>'; //closes a nav item
		echo str_repeat('</ul></li>', $ni->subDepth); //closes dropdown sub-menu(s) and their top-level nav item(s)
	}
}
echo '</ul>'; //closes the top-level menu

階層に応じて、ifがあって、表示する階層分だけ繰り返すように書かれています。
concrete5のブロックというか、テンプレのファイルには結構な量のコメントが書かれていて、それを読めばどうやってデータを取得出来るかがわかりやすいです。
コメント内に、下記のようなインフォメーションが記載されているので、それを参照しつつ、テンプレートを書き換えます。

 * Each nav item object contains the following information:
 *	$navItem->url        : URL to the page
 *	$navItem->name       : page title (already escaped for html output)
 *	$navItem->target     : link target (e.g. "_self" or "_blank")
 *	$navItem->level      : number of levels deep the current menu item is from the top (top-level nav items are 1, their sub-items are 2, etc.)
 *	$navItem->subDepth   : number of levels deep the current menu item is *compared to the next item in the list* (useful for determining how many <ul>'s to close in a nested list)
 *	$navItem->hasSubmenu : true/false -- if this item has one or more sub-items (sometimes useful for CSS styling)
 *	$navItem->isFirst    : true/false -- if this is the first nav item *in its level* (for example, the first sub-item of a top-level item is TRUE)
 *	$navItem->isLast     : true/false -- if this is the last nav item *in its level* (for example, the last sub-item of a top-level item is TRUE)
 *	$navItem->isCurrent  : true/false -- if this nav item represents the page currently being viewed
 *	$navItem->inPath     : true/false -- if this nav item represents a parent page of the page currently being viewed (also true for the page currently being viewed)
 *	$navItem->attrClass  : Value of the 'nav_item_class' custom page attribute (if it exists and is set)
 *	$navItem->isHome     : true/false -- if this nav item represents the home page
 *	$navItem->cID        : collection id of the page this nav item represents
 *	$navItem->cObj       : collection object of the page this nav item represents (use this if you need to access page properties and attributes that aren't already available in the $navItem object)

今回使用するのは、最後の行の「$navItem->cObj」で、英語がよくわからないながらも読んでみると、どうやら「
ナビアイテムに該当するページのコレクションオブジェクト(既に用意されている$navItemオブジェクト以外でページプロパティとか属性が必要だったらこれを使え)」って書いてあるっぽいです。なんとなく雰囲気で和訳してるので多少の間違いは勘弁してください。

で、コードを追加しますた↓

echo '<ul class="nav">'; //opens the top-level menu
foreach ($navItems as $ni) {
	echo '<li class="' . $ni->classes . '">'; //opens a nav item
	echo '<a href="' . $ni->url . '" target="' . $ni->target . '" class="' . $ni->classes . '">' . $ni->name . '</a>';
	if ($ni->hasSubmenu) {
		echo '<ul>'; //opens a dropdown sub-menu
	} else {
			$cobj = $ni->cObj; // ← $navItems->cObjを$cobjに入れる
			if($ni->level == 2 && $cobj->getCollectionDescription()) { //後述
			echo '<p>' . $cobj->getCollectionDescription() . '</p>';
		}
		echo '</li>'; //closes a nav item
		echo str_repeat('</ul></li>', $ni->subDepth); //closes dropdown sub-menu(s) and their top-level nav item(s)
	}
}
echo '</ul>'; //closes the top-level menu

順を追って説明すると、該当箇所は「$cobj = $ni->cObj;」から始まる4行です。

「$cobj = $ni->cObj;」で、インフォメーションにあった$navItems->cObjを変数にしました。

さらに、次の行のifの条件ですが、「$ni->level」を使用すると階層の深さが0から順に取得できますので、「$ni->level == 2」とすることで、「孫ページのみ」の条件指定ができます。汎用性持たせるなら、levelの値を数値じゃなくて、「一番大きい値」とか「最後の値」とか変数にしておいた方がいいかもですね。

さらに先ほど変数にした$cobjから「$cobj->getCollectionDescription()」を記述する事で、説明文が存在するかどうかの判別をしています。なので条件が「if($ni->level == 2 && $cobj->getCollectionDescription())」となっています。

で、最後にechoするだけ。なんということでしょう。今になって考えればこんなに簡単な事を、全然わからなくて2日くらいずっとやってました。アホです。

最終的に上記のカスタムテンプレートで、↓のようなマークアップになります。

<ul>
  <li><a href="oya">親ページ</a>
    <ul>
      <li><a href="ko">子ページ</a>
      <ul>
        <li><a href="mago">孫ページ</a>
     <p>説明文テキスト説明文テキスト説明文テキスト説明文テキスト説明文テキスト</p>
      </ul></li>
    </ul></li>
</ul>

以上。

メモ:concrete5のページ属性で指定した画像を、カスタムテンプレートから表示する方法

ページリストで、記事ページのサムネイルブロックを表示する方法もあるのですが、ケースバイケースで属性から画像入れた方が良い場合もございまして、
以前テーマファイルに属性の画像を表示する方法を書きました。
メモ:concrete5のページ属性で指定した画像を表示する方法

以前の記事の内容ではちょっと問題がございました。
↓以前の書き方

<img src="<?php echo ($c->getAttribute('ハンドル')->getVersion()->getRelativePath());?>" alt="" />

これ、カスタム属性に画像ファイルが入ってないとエラーが出てしまいます。

↓なので、個人的には画像があるときだけ表示するという方法を取るのが望ましいのかと思いますね。

<?php
  $変数 = $c->getAttribute('ハンドル');
  if($変数) {
    echo '<img src="' . $変数->getVersion()->getRelativePath() . '" alt="" />';
  }
?>

そしてカスタムテンプレートで表示する場合は、

$c->getAttribute('ハンドル')

を↓

$cobj->getAttribute('ハンドル')

に書き換えると対応できました。

[concrete5]悲劇的!Designer Contentの落とし穴

結論

いきなり結論です。

Designer contentを使用してブロックを作成し、間違えて作成したブロックを削除する際には、
「FTP上のblock/”Dir”」と、「データベース内のblocktypeにある”Dir”」の両方を削除してください。
※”Dir”はブロックタイプ作成時の任意です。

実ファイルとデータベースのテーブルを削除しないと思わぬエラーの原因となります。

なお、以下は今日起こった現象の振り返りなので、あまり意味がありませんのであしからず。

ブロックが追加出来ないよ!?

本日、concrete5をご利用のクライアントのサーバー移行作業を行っていた所、「ブロック追加」が一切機能しなくなりました。
「あれれー、おかしいなぁー」と思い、管理画面からブロックタイプを開こうとした所、Internal Server Error 500との事。

はてさて、一体何なんでしょうか。
何はなくともエラーログを見る習慣付けは必要だと思いました。全く関係のないアドオンを消したりしてまた入れ直したり、とても面倒な事をしてしまいました。
エラーログを拝見いたしました所、2つのエラーの記録がございました。

エラーの内容

[code]
[error] [client xxx.x.x.x] PHP Warning: require_once(/home/httpd/public_html/updates/concrete5.6.0.2.ja/concrete/blocks/links/controller.php): failed to open stream: No such file or directory in /home/httpd/public_html/updates/concrete5.6.0.2.ja/concrete/core/libraries/loader.php on line 205, referer: https://xxx.xxx.xxx.xx/index.php/dashboard/

[error] [client 219.8.4.64] PHP Fatal error: require_once(): Failed opening required ‘/home/httpd/public_html/updates/concrete5.6.0.2.ja/concrete/blocks/links/controller.php’ (include_path=’/home/httpd/public_html/libraries/3rdparty:/home/httpd/public_html/updates/concrete5.6.0.2.ja/concrete/libraries/3rdparty:.:/usr/share/pear:/usr/share/php’) in /home/httpd/public_html/updates/concrete5.6.0.2.ja/concrete/core/libraries/loader.php on line 205, referer: https://xxx.xxx.xxx.xx/index.php/dashboard/
[/code]

サーバー移行と同時にconcreteのアップデートも行ったのですが、アップデート前は問題なく利用出来てたというところがポイントです。

で。

エラーの内容は、「そもそも/home/httpd/public_html/updates/concrete5.6.0.2.ja/concrete/blocks/links/controller.phpってファイルがおかしいじゃんか、無いじゃんかー。」って仰るわけです。
私としましても、「うーん、そんなブロックは使ってないよなぁー。」と頭を抱えるしかございませんでした。

救世主は移行前のサイトでした

Designer contentは非常に便利なアドオンで、ブロックの内容を自由に組み立てる事ができます。
ただ、弱点が一つあって、Designer contentでブロック作成をする際に、内容を間違えて登録してしまった時です。
間違えて登録してしまった後に、管理画面から修正を行おうとしても出来ないという弱点があって、簡単に順番の入れ替えや、静的タグの追加くらいなら、直接生成されたphpファイルをいじれば直せるのですが、テキストフィールドの追加を忘れてしまった場合は別のブロックタイプをDesigner contentで新たに作成し直すしかないのです(一応方法はあるのでしょうが、私はphpに詳しくないので作り直した方が速い。)

そう、過去の負の遺産が残っておりました。

間違えて作成してしまったブロックタイプを、FTPからディレクトリごと削除していました。
移行前の方では、ディレクトリが存在していないにも関わらず、動作していました。

でも、データベースには作成したブロックタイプは残っているので、concreteのcoreにある「/concrete/core/libraries/loader.php」は居なくなってしまった「/block/links」を探し続けてしまいます。

ここからは推測ですが、管理画面からアップデートをかけた際に、concreteのcoreファイルのパスが変わる関係で、アップデート前ではディレクトリが無くてもごまかして動いていたものが、動かなくなってしまったと考えています。

Designer contentを使用してブロックを作成し、間違えて作成したブロックを削除する際には、
「FTP上のblock/”Dir”」と、「データベース内のblocktypeにある”Dir”」の両方を削除してください。
※”Dir”はブロックタイプ作成時の任意です。