4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

EC-CUBEで動的にブロック配置をする〜フロント側〜

Last updated at Posted at 2015-03-24

こんにちは。たかぴーです。

EC-CUBEで動的にブロック配置をする

EC-CUBEには、ブロックレイアウトの管理機能があって、メインコンテンツを真ん中に据えて、周りにブロックと呼ばれる小さなパーツを並べられる。
もちろんブロック自体が独立して動いていて、どこにでも配置できるような形で。

ちなみにblocなのかblockなのかアヤシイ。

Silexベースで実装してみた

View

まず、Viewの設計から。
できれば大元ではワンライナーで呼び出してるっぽくしたいと思い、以下のような呼び出しを想定。

site_main.twig

    {{ render(path('bloc', {'position': 'HEAD'})) }}

こうすることで、site_main.twigの見通しがダンチ。

次にbefore()ミドルウェアを使って、DIコンテナに突っ込む。
こうすることでサブリクエスト時には動作せず、何回もクエリが投げられずに済む。

Eccube/Application.php
$app->before( function(Request $request, Application $app) {
            $qb = $app['orm.em']->createQueryBuilder()
                ->select('p, bp, b')
                ->from('Eccube\Entity\PageLayout', 'p')
                ->leftJoin('p.BlocPositions', 'bp', \Doctrine\ORM\Query\Expr\Join::WITH, 'p.page_id = bp.page_id OR bp.anywhere = 1')
                ->innerJoin('bp.Bloc', 'b')
                ->andWhere('p.device_type_id = :device_type_id AND p.url = :url')
                ->addOrderBy('bp.target_id', 'ASC')
                ->addOrderBy('bp.bloc_row', 'ASC');

            $result = null;
            try {
                $result = $qb->getQuery()
                    ->setParameters(array(
                        'device_type_id'    => 10,
                        'url'               => $url,
                    ))
                    ->getSingleResult();
            } catch (\Doctrine\ORM\NoResultException $e) {
            }
            
            $app['eccube.layout'] = $result;
        });

続いて、

site_main.twigから呼び出されるControllerはこちら。
ただtargetIdに合致する配列だけを引っ張って$blocに突っ込んでるだけです。

BlocController.php

namespace Eccube\Controller;

class BlocController
{
	public function index(Application $app)
	{
		$position = $app['request']->get('position');

		$blocs = array();
		
		if ($app['eccube.layout']) {
	        foreach ($app['eccube.layout']->getBlocPositions() as $blocPositions) {
	        	if ($blocPositions->getTargetId() == constant("Eccube\Entity\BlocPosition::" . $position)) {
	        		$blocs[] = $blocPositions->getBloc();
	        	}
	        }
	    }

	    return $app['twig']->render('bloc.twig', array(
	        'blocs' => $blocs,
	    ));
	}
}

View側は、ループ回してそれぞれのblocのcontroller呼びに行ってるだけなので割愛。

サブリクエストにすることで、before()は1回しか通らないし、リクエストも無駄に投げられないしで、作りながら「もし◯◯だったらどうしよ...」っていうのをことごとく回避してくれてました。
symofnyって本当によく考えられたフレームワークですよね。

というわけでまた次回〜!

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?