Magento: Add (and retrieve) custom database field for CMS pages - mysql

I want to assign custom parameters to CMS pages in Magento (i.e. 'about', 'customer service', etc), so they can be grouped.
The end goal is to use the parameters for each page to show (or hide) them in a nav menu. Writing a quick method in the page/html block to retrieve the pages (active only) for the menu was easy, but I can't figure out how to group them so that 'testimonials', 'history', and 'contact' are associated with 'about', and 'return policy', 'shipping', and 'contact' are associated with 'customer service'.
Any help to point me in the right direction would be greatly appreciated.
Thanks!

Unfortunately the cms pages are not entities and custom attributes are not supported.
My suggestion will be to overload Mage_Cms_Model_Page, create an associated table with your data, and in the new class constructor assign a new property to your_page object.

Perhaps just use URL key field in admin as your category denominator? E.g:
CMS page 1 URL key: about/testimonials
CMS page 2 URL key: about/history
CMS page 3 URL key: about/contact
CMS page 4 URL key: customer-service/return-policy
...
Then just loop through them in your template or have a method in a custom block class to group them together using regex based on the first part before slash.

Did you look for using of setData / getData for storing custom values? It works me well for custom blocks - I set value in controller and read it at block rendering.

I decided to go in a different direction with this. Here is what I did.
In admin interface:
Created static blocks for each page (i.e. 'Page: About')
Created a product category called CMS (URL Key: content), set Is Active to 'no'
Created child categories for each content category (i.e. 'about'). Set Is Active to 'yes' and Display Mode to 'Static block only' and selected corresponding static block.
Created child categories for each content category as above.
In code:
Created two new methods in (local copy of) Catalog/Block/Navigation.php to get the current parent category and its children:
public function getNavCategory($category)
{
if($category->getLevel() == 3){
return $category;
} else {
$parentCategory = Mage::getModel('catalog/category')->load($category->getParentId());
return $parentCategory;
}
}
public function getNavChildCategories($category)
{
$layer = Mage::getSingleton('catalog/layer');
/* #var $category Mage_Catalog_Model_Category */
$categories = $category->getChildrenCategories();
$productCollection = Mage::getResourceModel('catalog/product_collection');
$layer->prepareProductCollection($productCollection);
$productCollection->addCountToCategories($categories);
return $categories;
}
Created a modified version of app/design/frontend/MYINTERFACE/MYTHEME/template/catalog/navigation/left.phtml to iterate through categories and child categories. Working example at: http://67.228.100.26/content/about

Related

get_fields is empty after inserting an ACF gutenberg block

we just integrated timber into our acf-gutenberg-block setting, and we love it. ;)
There is one thing that doesnt work.
Our ACF Blocks have prefilled values like a "dummy" headline.
But when a backend user adds a block into the gutenberg view, the get_fields() inside our render_callback function is empty. The user then changes the headline and then get_fields brings up all the fields and their values.
any idea how to fix this problem on the first load of an acf block?
the callback function looks like this (just like the one in the documentation)
function my_acf_block_render_callback($block, $content = '', $is_preview = false)
{
$context = Timber::context();
// Store block values.
$context['block'] = $block;
// Store field values.
$context['fields'] = get_fields();
// Value for detecting editor-view in twig (like is admin())
$context['is_preview'] = $is_preview;
// Render the block.
Timber::render('blocks/' . $block['template-name'] . '.html.twig', $context);
}
cheers,
ToM

How can I use Render sub-template in a C# template in a Content module that uses lists within lists?

2SXC 10.25.2 / DNN 9.3.2
I have a 2sxc module that uses a C# template with "list" enabled. I have a content type called "pathway" and inside that I have 2 entity picker fields for "first step sessions" and then "next step sessions". These entity pickers use a "session" content type. Inside each of those "session" content types I also have an entity picker for "speaker(s)". All in all, it's a setup that I have lists within lists within lists.
When I create the loops for each of the sublists, I can easily do that within the 1 C# template but it becomes repetitive, long, and unruly because there's so much c# code where I'm looping the same session template for different entity picker sections. So, I tried using the "Render sub-template" code to simplify the template - I created new sub templates and inserted them in - it seemed to work at first, however, the template started outputting all "session" items into each item in the list.
I suspect that the subtemplate somehow loses the context of the item that it's in so it's outputting everything. Is there something special I need to know about using subtemplates with for each loops? Do I have to include params and, if so, how do I do that?
EDIT to include code sample:
Here is a small, simplified version of the code I'm working with:
#foreach(var Content in AsList(Data)) {
<h2>#Content.Title</h2>
<h3>Lead Sessions</h3>
<div class="lead-sessions text-green">
#foreach(var item in AsList(Content.LeadSessions as object)){
<h4>#item.LeadSessionTitle</h4>
<p>#item.LeadSessionText</p>
}
</div>
<h3>Next Sessions</h3>
<div class="next-sessions text-green">
#foreach(var nextitem in AsList(Content.NextSessions as object)){
<h4>#nextitem.LeadSessionTitle</h4>
<p>#nextitem.LeadSessionText</p>
}
</div>
}
I want to make a subtemplate so I don't have to repeat the same code for the sessions loop. How could I simplify this template to use a subtemplate for looping the sessions within the lead-sessions and next-sessions?
So based on the modified question, it's a bit like this
#foreach(var Content in AsList(Data)) {
<h2>#Content.Title</h2>
<h3>Lead Sessions</h3>
#RenderPage("_inner.cshtml", new { Items = Content.LeadSessions })
<h3>Next Sessions</h3>
#RenderPage("_inner.cshtml", new { Items = Content.NextSessions })
}
Second file _inner.cshtml
#{
var items = AsList(PageData["Items"]);
}
<div class="next-sessions text-green">
#foreach(var nextitem in items){
<h4>#nextitem.LeadSessionTitle</h4>
<p>#nextitem.LeadSessionText</p>
}
</div>
Yep, you can just use RenderPage without params, or pass in params like in the blog app:
#RenderPage("shared/_Category Filter.cshtml", new { MobileView = true, FilteredCategory = filteredCategory })
See https://github.com/2sic/app-blog/blob/master/_List.cshtml#L25
Then the template can retrieve the values like
#{
var filteredCategory = PageData["FilteredCategory"];
}
See https://github.com/2sic/app-blog/blob/master/shared/_Category%20Filter.cshtml#L6
You can pass around any amount of values/objects like this.
You can also create helpers - and then call those helpers. Like this
https://github.com/2sic/app-news/blob/master/shared/_Helpers.cshtml#L24-L33

Add #id suffix to RedirectToAction() in controller ASP NET MVC

Somehow I find this hard to describe, but here I go:
I have a div in my SelectClasses Razor view page with an id="id152".
In order for me to show that div on the page at reload, I have to add the suffix #id152 to my page url.
<div id="id152">blabla</div>
...
..
Section 7
Now my question: Is there a way to add/pass this suffix to a 'RedirectToAction()'?
public ActionResult Index()
{
//All we want to do is redirect to the class selection page and add a suffix
return RedirectToAction("SelectClasses", "Registration", new { id = 99 })); //add suffix here somewhere
}
So when my SelectClasses view is shown, the url looks something like this:
'[url]/SelectClasses/99#id152'
The RedirectToActionResult (among the rest of RedirectTo* results) is meant to be used for generation of URLs based on registered routing data.
In your case, you wish to concatenate a hash parameter value (#id152) that is not being sent to the server and only used by the browser. That's why said methods don't bother dealing with it.
I suggest you do this instead:
var redirUrl = Url.Action("SelectClasses", "Registration", new { id = 99 });
redirUrl = String.Concat(redirUrl, "#id152");
return Redirect(redirUrl);

Add ACF fields to Post Edit Admin Page / edit.php

I am trying to add a few custom fields to the edit.php page ( Post List Page )
It is a few settings like asking the user whether post must be displayed in 2,3 or 4 columns w, and I specifically want it on this page.
I have found a way to add content with a function to the right place without editing the wp-admin/edit.php or wp-admin/custom-header.php
add_action( 'load-edit.php', function(){
$screen = get_current_screen();
if( 'edit-post' === $screen->id )
{
add_action( 'all_admin_notices', function(){
echo '<h2> === Add ACF Fields here === </h2>';
});
});
i am also halfway in adding a location rule in ACF:
add_filter('acf/location/rule_types', 'acf_location_rules_types');
function acf_location_rules_types( $choices ) {
$choices['Post']['post_edit_screen'] = 'Post Edit Screen';
return $choices;
}
But how do now create a location rule to show my ACF fields here?
Thank you
I spent hours trying to extend the ACF_Location class without success.
The ACF Extended WordPress plugin provides the desired functionality.
You can find the GitHub repo here.
I believe this is the class that extends the ACF location functionality we both needed. #see acfe_location_post_type_archive class here

tumblr custom content per tagged category

With tumblr, I need to add custom title and description meta tags on tagged category pages.
such as url.com/tagged/lifestyle needs different title/description than url.com/tagged/history
Does anyone know a block level conditional for this, or a way to make custom templates for each tagged category?
I can manipulate the title using a hack via jQuery, but this will only run on page load.
//Add an id to the title tag:
<title id="chTitle">Tumblr Blog</title>
// get the current page url
$href = document.location.href;
$primaryDir = document.location.pathname.split("/")[1];
$secondaryDir = document.location.pathname.split("/")[2];
if($secondaryDir == 'lifestyle') {
$('#chTitle').text('Lifestyle');
}else if($secondaryDir == 'history') {
$('#chTitle').text('History');
}else{
$('#chTitle').text('Title Default');
}
You could actually just take the secondary directory and pass it as a variable into the page title.
$('#chTitle').text($secondaryDir);
But you would need a default fallback for pages with no secondary dir. blog.tumblr.com/submit etc.