TYPO3 7.6后端模块:多表数据列表展示开发求助
Hey there! I totally get how tricky it can be to set up a multi-table listing in TYPO3 7.6's backend, especially when working with Extension Builder-generated models. Let's walk through a practical, step-by-step solution tailored to your e-commerce extension's three models: Product, Productsorder, and ProductsorderPosition.
First, make sure your model relations are correctly configured in Extension Builder—this is the foundation for pulling combined data:
- For Productsorder: Add a relation to the
fe_userstable (your customer) as a "Relation to existing table" (usually 1:1, since each order belongs to one customer). Also ensure it has a 1:n reverse relation toProductsorderPosition(Extension Builder will auto-generate this if you set up the relation from the ProductsorderPosition side). - For ProductsorderPosition: Add two core relations: one to
Productsorder(1:n, each position links to one order) and one toProduct(1:n, each position links to one product). Don’t forget your custom fields likequantity(integer) andspecification(text/input). - For Product: Confirm the reverse relation to
ProductsorderPositionexists (Extension Builder handles this automatically when you set up the ProductsorderPosition → Product link).
Default Extension Builder lists only single tables, so we’ll create a custom module to display your combined data. Add this to your extension’s ext_localconf.php:
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerModule( 'Vendor.' . $_EXTKEY, 'web', // Attach to the "Web" main backend module 'orderoverview', // Unique key for your module '', // Position (empty = top of the module list) [ 'OrderOverview' => 'list' // Controller and action to use ], [ 'access' => 'user,group', 'icon' => 'EXT:' . $_EXTKEY . '/Resources/Public/Icons/module-order-overview.svg', 'labels' => 'LLL:EXT:' . $_EXTKEY . '/Resources/Private/Language/locallang_orderoverview.xlf', ] );
Don’t forget to add the language labels and icon file to match your setup.
We’ll use Extbase’s query builder to join the three tables and avoid slow lazy-loading issues.
First, add a custom method to your ProductsorderRepository:
public function findAllWithPositionsAndProducts() { $query = $this->createQuery(); $query->getQuerySettings()->setRespectStoragePage(false); // Skip storage page restriction if needed // Join Productsorder with ProductsorderPosition $query->join( $this->getAlias(), 'Vendor\YourExtension\Domain\Model\ProductsorderPosition', 'position', $query->equals('position.productsorder', $this->getAlias()) ); // Join ProductsorderPosition with Product $query->join( 'position', 'Vendor\YourExtension\Domain\Model\Product', 'product', $query->equals('product', 'position.product') ); // Order by most recent orders first $query->setOrderings(['crdate' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING]); return $query->execute(); }
Then, create an OrderOverviewController with a listAction to call this method:
class OrderOverviewController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController { /** * @var \Vendor\YourExtension\Domain\Repository\ProductsorderRepository * @inject */ protected $productsorderRepository; public function listAction() { $orders = $this->productsorderRepository->findAllWithPositionsAndProducts(); $this->view->assign('orders', $orders); } }
Create Resources/Private/Templates/OrderOverview/List.html to render the joined data. We’ll display each order’s positions in a single table, with merged cells for repeated order details:
<f:layout name="Default" /> <f:section name="Content"> <h1>Order Overview with Products</h1> <table class="tx-yourextension table table-striped"> <thead> <tr> <th>Order ID</th> <th>Customer</th> <th>Product</th> <th>Quantity</th> <th>Specification</th> <th>Order Date</th> </tr> </thead> <tbody> <f:for each="{orders}" as="order"> <f:for each="{order.productsorderPositions}" as="position" iteration="posIter"> <tr> <!-- Show order ID only for the first position in the order --> <td><f:if condition="{posIter.isFirst}">{order.uid}</f:if></td> <td><f:if condition="{posIter.isFirst}">{order.customer.name}</f:if></td> <td>{position.product.title}</td> <td>{position.quantity}</td> <td>{position.specification}</td> <td><f:if condition="{posIter.isFirst}"><f:format.date format="Y-m-d H:i">{order.crdate}</f:format.date></f:if></td> </tr> </f:for> </f:for> </tbody> </table> </f:section>
- Use
\TYPO3\CMS\Core\Utility\DebugUtility::debug($orders);in your controller to verify the joined data is being fetched correctly. - Ensure backend users have access to the
fe_users,tx_yourextension_domain_model_productsorder, andtx_yourextension_domain_model_productsorderpositiontables. - If you rely on storage pages, adjust the
setRespectStoragePagesetting in the repository method totrueand assign the correct storage page IDs to your module.
Hope this gets your multi-table listing up and running smoothly! Let me know if you hit any snags with specific parts.
内容的提问来源于stack exchange,提问作者Kathara

