I'm trying to move the HTML that renders a product box (everything that's in the product-item-info div when products are rendered in a loop on list.phtml). This is on Magento 2.4.3-p1.
I need to do this as I want to re-use the same layout in a couple of places in the site - for example, to render a custom selection of products on the homepage and probably re-use the same box for related products when viewing a single product. Currently, I have to maintain the same code in two places.
I assumed I should be able to define a new block such as product.list.box by adding an entry into catalog_category_view.xml such as:
<block class="Magento\Framework\View\Element\Template" name="product.list.box" as="product_list_box" template="Magento_Catalog::product/product-box.phtml">
I would then reference in my list.phtml template such as echo($block->getBlockHtml('product_list_box'));.
However, this doesn't render anything, but I think also creates a problem that I need to inject a custom ViewModel, as well as setting the product to render and pass in other dependencies (such as the $viewMode, $imageDisplayArea and a bunch of other things the standard Luma theme needs to render a product).
So, what's the correct way to move the rendering of a product box into another template? As a relatively new Magento developer, this seems like it should be straightforward, but I can't get the right combination of code to achieve it.
If you define a new block, don't forget to define it's position. First, use <referenceBlock> or <referenceContainer> to define the place you want to put your block.
Then in your block, you can make good use of before or after attributes to define the position of your new block.
You can refer to Official Document for more usages and examples.
Related
I have a Home page on the Drupal website (such as is created after installation), but I still need to create this page:
What is the best way to create a page so that I can then add these posts with images?
I am just starting to learn Drupal and have heard so far about such ways of creating pages:
1) in admin toolbar: Content / Add Content / Article
2) in admin toolbar: Content / Add Content / Basic page
3) in admin toolbar: Structure / Views / Add Views
Which one should I use? Or maybe there is some other option that I don’t know about?
P.S. At the moment I am more interested how to create empty page on which I can then add posts later, and adding posts it is another question.
Welcome to Drupal.
Drupal ships with the default theme which won't look nice but it does its job in the right way. Now if you want to create a better UI/UX obviously you should create a new theme. But before that make sure to read and understand the concepts behind Drupal. Drupal docs are your first friend.
Drupal Documentation
Drupal considers everything as nodes and that's how Drupal got its power. As you mentioned, Articles, Basic Page etc are called content types and they can be used to create a particular type of content.
Now for your purpose create a new content type and add the fields you need. From the image above I can say your content type needs Title, Image, Category and Date. After creating content type you can create as many contents as you want under the content type you just created. Consider each card in your image as content.
Now you can use a Drupal Core Module Views, to perform DataBase Operations without writing single code. Yes, you can select fields, sort, order etc with Views UI and display it in a page or a part of a page (Block).
I would say just try this out in the default Drupal theme and when you understand how this works, you can start creating your own theme for your project.
Theming Drupal
There is a lot of resources available. But you have to make sure what you are asking is whether you actually need. It will take some time, but it worth.
To build layouts for homepages on Drupal 8 you best friend is https://www.drupal.org/docs/8/core/modules/layout-builder
To build the content blocks inside your home page, you should start creating nodes on a node content type to hold your information. For instance: news content type, with a title, a body, a date, and an image.
For every node type, ex. news, work on the preview display, full display, and any other display which makes sense. These displays can be used later in the Layout Builder directly or in Views, referenced below.
If you wish your list to be dynamic, such as the last 10 entries are shown first, then use a view to hold the content sorted and filtered as you need.
In a nutshell.
Create a content type for your article/news.
Modify the displays of the content types to have at least a summary and full view.
Create the content itself to have something to see.
Create the view (block) to filter and sort your content.
Create a page layout (this makes sense for landing pages) which places your new view and any other content you need in any disposition.
This is roughly what I would do. The steps described above contain many intermediate steps. If in doubt, check the docs.
I hope that helps!
First, decide what will you display on that page. Is it content in some existing content type (article maybe) or you want to crate new one for this purpose.
If you need new one then create it (Structure -> Content types -> Add content type).
Then check what fields will you need. I.e. image, some description text. Add missing ones.
Create few nodes (pages) in that type so you could work with them.
Then for displaying you should crate a view (Structure -> Views -> Add view). It can be a page view (you are displaying only that content on page) or block view (this is just a block among some others). If you create a page you could visit it and if you create a block you have to add it to some region to appear on page (Structure -> Block Layout).
Inside your theme you should create templates for this page/block. Turn on twig debug mode so it will show you hints - what templates are used and how can you name yours to override default ones.
Adjust CSS to make it look like you want it to look.
Find some tutorial(s) for the details
Previous answers have given the flow of the work you should go through, I would like to add some resource that might help you achieve this.
Creating content type and fields: https://www.drupal.org/docs/administering-a-drupal-site/managing-content-0/working-with-content-types-and-fields
https://www.drupal.org/docs/user_guide/en/structure-content-type.html
View and View modes: https://www.drupal.org/docs/user_guide/en/views-concept.html
https://www.drupal.org/docs/8/api/entity-api/display-modes-view-modes-and-form-modes
Handling block of the view: https://www.drupal.org/docs/8/core/modules/block/overview
Feel free to ask if any further explanation is needed.
Thank you
I'm customizing my Magento webstore to use rich snippets, so that I had changed the price.phtml to add the itemprop="price" to the price span. The problemn is that I'm getting various itemprop attributes when I have related or agregate products.
I would like to know if there is a way to get the block parent name in php, so I'll be able to ignore the itemprop rendering out of the main product.
The price.phtml template and the corresponding block is almost always called via Mage_Catalog_Block_Product_Abstract::getPriceHtml($product, $displayMinimalPrice, $idSuffix), and therefore has no parent.
To detect from which blocks it is used, you could update those blocks to add something like $product->setIsCalledFromParentBlock(true) before the getPriceHtml() call, and then test the value of $product->getIsCalledFromParentBlock() in price.phtml
I would advise you to get a developer-toolbar extension like mgt-commerce is offering one for free! You get all kind of information straight in your webbrowser.
Good luck!
Let me first explain what I am trying to do.
In joomla 3.0 I have created a Menu_Item_Text_Separator override for my template http://docs.joomla.org/Help30:Menus_Menu_Item_Text_Separator. It seems as though joomla will only recognize one default Text separator per template which is ok if you just want the one. but I ideally would like to have the choice of selecting the custom one in my template folder as well as the default one that joomla recognizes. To inform you this is what I have done to make it happen.
in my template I have a folder named html which had a folder called mod_menu inside it.
In the mod_menu folder I have the .php files called:
default_separator.php
custom_separator.php
I then go into menu manager and edit the menu item for which I want to display a text separator for.
I then go to 'template style' http://docs.joomla.org/Help30:Menus_Menu_Item_Text_Separator and look for my custom style. but I only can choose the default one.
So i wonder if this is way that joomla works that you can only have one default per template. but is it possible to have more than one?
any advice most welcome.
regards
w9914420
Sorry this got too long for a comment.
Okay let's start from the beginning. Templates have a set of parameters defined in the templateDetails.xml file. A template style is simple a record containing the information about a template and the array of parameter options you have selected. You can make as many template styles as you want for a given template Each one has its own name. In the menu you can select any of the styles and assign it to a menu item. ....
What you are talking about has nothing to do with template styles. You are talking about using a layout override for mod_menu. Because you are using a file with the same name as a core layout file you should get a 1:1 replacement.
From what I understand of what you want to do, you should instead make a new named replacemen both for default_separator and for default.php. THat's because the alternative layout field is going to look for a replacement for default.php say yourname.php and then in that replacement when you load a template called separator it is automatically going to look for yourname_separator rather than default_separator because it assumes you are appending the _separator to the base name. If you do this it has some advantages such as you will be able to make a more complex layout and it will allow you to load different sub layouts conditionally for example.
I think your are confusing template styles with the style for menu module. Unless you have a parameter in your template that specifies the choice of a mod_menu layout a template style is not going to help you.Go to he module manager and pick the module you want to apply the style to. Use the field to select the layout you want. Or if it is a css style use the style option. It could also be that what you really want is to apply module chrome. THat do can be done by editing the module. If you want to have the same menu with different layouts or styles you'll probably want to make additional modules for that menu.
I had a rethink of what i was trying to do. What I was trying todo could not be achieved through the method I hoped - creating a template for that one text separator would not be practical although I have now discovered how to feed template parameter values into layout overrides.
Thank you Elin for your time
regards w9914420
I'm new to Drupal dev, and was trying to add an existing region variable to my module's preprocessor function.
Basically, I've created a new region for my site (here's the definition from within side my theme's .info file):
regions[feeds] = Feeds
From Administer->Blocks, I've added the blocks I want to the new "Feeds" region.
Then, from another module, the "Advanced Front Page" module, I'm trying to add some PHP to my "front page" inside this module. The Advanced Front Page module just allows the site to have a landing page, instead of immediately viewing a list of other site content, etc. I've enabled PHP for the content area, and then added the following:
<div>
<?php print $feeds; ?>
</div>
It does not print the "Feeds" region, and I believe it's because that region variable is not accessible from outside of the page.tpl.php file. So after looking around, I came upon these links:
http://drupal.org/node/223430
http://drupal.org/node/237391
From there, I tried to add a preprocessor function for the module "Advanced Front Page", which has a module name of "front_page" (or possibly just "front", I'm not 100% sure). Here's my preprocessor function, that I tried to add to both my template.php file, and the /modules/front/front_page.module file (not at the same time, mind you):
function front_preprocess(&$vars)
{
$vars['feeds'] = theme('blocks', 'feeds');
}
Regardless of where I've placed this file (template.php or front_page.module) it doesn't seem to do anything. Any idea where I might be going wrong?
There are several points to address in your question:
I'd second googletorps answer in that you should approach this in a different way.
The *_preprocess functions can only be used to manipulate/inject variables for templates or theme functions, e.g. page.tpl.php, node.tpl.php, theme_links(), etc. As the front_page module does not use a theme function or (special) template to render its output, you can not make the $feed variable there by means of a *_preprocess function.
Sidenote: With *_preprocess functions, naming is crucial. You need to prefix the function name either with the exact module name or the theme name, depending on where you declare it. So in your example, if you want to add a preprocess function to the module, you'd prefix it with 'front_page_', if you add it to your themes template.php, you'd add 'yourThemeName_'.
You could achieve what you want by creating the blocks directly from code in your frontpage content area. Instead of trying to output the (not available) $feed variable, you could call:
theme('blocks', 'feeds')
This will cause Drupal to return the themed blocks for the given region ('feeds' in this case). Note that this is still not a good way to do it, as even if you don't use the region in your page.tpl.php, it still gets created for every page request made to your site!
So I would go with googletorps suggestion, adding the new region only if there are other uses for it also. If I'd just wanted to add some blocks to the frontpage, I would not create a new region, but configure the blocks to show in the content region and simply restrict them to show only for <front> in their visibility settings.
I haven't tried the advanced front page module, but when dealing with regions, you shouldn't do what you have done. It's a bit hacky and actually not needed. I don't know how the module hook into the templating system, but your problem is probably getting region variables into it's scope. But instead of trying to get the region into the frontpage using the module, you should instead get it into your page.tpl.php. You can actually do what you first tried, but I would suggest that you alter it a bit like this:
<?php if ($feeds): ?>
<div id="feeds">
<?php print $feeds; ?>
</div>
<?php endif; ?>
I have improved in two ways.
By adding the if statement, you don't add empty markup. So you wont get an empty div if $feeds doesn't contain anything.
Adding id's to regions is a good idea. It makes styling them or their content a lot easier, also it adds semantic to your page which html is all about.
Now if you only want your blocks to be shown in the front page you can set that up in each of the blocks settings. So you could possibly just use a region that already exist, unless you want your blocks display a outside an existing region. When adding regions it's not a good practice to only add a region to a single page, instead it's much better to control when it's content should be shown. It might be that you don't need to create a new region, but simply can use one that's already made. Also if you want to make some template changes to your front page, you can also create the front-page.tpl.php where you can create a different template layout for your front page if you so desire.
I've created a new content type called Homepage, which has a number of fields. The fields are node references to the Single Image Promo content type. Single Promo Box has fields for title, text and image. The idea is that I can create multiple copies of a Single Promo Box, each with different field values. I then want to place a few of them on the homepage.
So I can place a specific Single Image Promo on the homepage fine now. But what template file do I need to create to style the way Single Image Promo is shown when it's a node reference on the homepage?
Thanks,
Maria
It sounds like you are over complicating things.
If you want to create some different boxes on your homepage, using node reference is not the right way to go about this. There are some few different ways to do what you want, the easiest i probably to create a block view of the node you want to display. When you turn a node into a block, you get the ability to place it in any of your theme's defined regions.
You could also just create a view and from there get the different Single Image Promo you want without using node reference at all. Views has a lot of different filters, which will enable to you create a view that always displays the right nodes. This solution wont work well, if you want to place the nodes in different regions though.
To answer your question, when nodes are being displayed, they will by default be rendered with the node.tpl.php template file. To make specific templates for each of your node types, you can create a new template named node-nodetype.tpl.php, where nodetype is what you called the node type when you created it.
node-nodetype.tpl.php can work to a certain degree, but in that file you are styling the entire page, with the content type's fields delivered wholesale to the tpl via a single $content variable. Maybe it is enough for you, but if you need finer grained control:
You can edit and style the individual content type's fields with the Content Template (contemplate) module. It provides access to all of a content type's fields within the $content variable (which is delivered wholesale to the node-nodetype.tpl.php. The contemplate is php, so you can add logic and conditional formatting for the node-reference fields (usually clearly labeled in the contemplate).
And don't overlook the simple solution of the content type's 'display fields' tab (next to manage fields tab), where you can control some field outputs right out of the gate.