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

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

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

WordPress: Calling a shortcode for a value in a different shortcode

I'm very new to this, so please go easy on me if this is a dumb question.
I am building a site with events manager and geo my WordPress plugins. I want a user to be able to input their autofill location (via GMW) and have the calendar in EM output only events a certain distance from that location. I have already gotten (with handholding) to a point where I have a shortcode that spits out the coordinates of the location entered. The EM full calendar shortcode takes an attribute called 'near' which takes coordinates and subsequently outputs the desired calendar.
Code at the moment:
[fullcalendar near=[gmw_current_latlng] near_distance=20]
with [gmw_current_latlng] normally returning the lat and long separated by a comma. Normally, the near att takes say 50.111123,-45.234, etc.
My problem is that it seems that I cannot get what I want with this hardheaded approach. Again, I'm very new to coding and don't know much, but I've been working on this problem for weeks and have not found an answer. I've tried many different routes, but this way has brought me oh so close to where I want to be.
The GMW dev said this about the problem:
"The thing is that I am not even sure if you can pass a value to a
shortcode using another shortcode. I’ve never tried this myself. The
best way would be to use filters and a custom function to “inject” the
coords directly into the calendar function."
If he is right and it's not possible, I have no idea how to carry out his second suggestion. Hopefully, I can get this sorted out because frankly, my site depends on it working.
As #Jeppe mentioned, you can do Nested Shortcodes:
[shortcode_1][shortcode_2][/shortcode_1]
But the parser does not like shortcode values as attributes in other shortcodes.
It sounds like you're reliant on a few plugins and their shortcodes, so I don't suggest editing those shortcodes - but if you look at the Shortcode API it's pretty easy to add you own. For simplicity's sake, this example won't contain the "proper" methods of making sure the shortcodes exist/plugins are installed etc, and will just assume they are.
// Register a new shortcode called [calendar_with_latlng]
add_shortcode( 'calendar_with_latlng', 'calendar_with_latlng_function' );
// Create the function that handles that shortcode
function calendar_with_latlng_function( $atts ){
// Handle default values and extract them to variables
extract( shortcode_atts( array(
'near_distance' => 20
), $atts, 'calendar_with_latlng' ) );
// Get the current latlng from the gmw shortcode
$gmw_current_latlng = do_shortcode( '[gmw_current_latlng]' );
// Drop that value into the fullcalendar shortcode, and add the default (or passed) distance as well.
return do_shortcode( '[fullcalendar near='. $gmw_current_latlng .' near_distance='. $near_distance .']' );
}
Provided [gmw_current_latlng] returns a useable format for your [fullcalendar] shortcode, you should now be able to use your new shortcode that combines the two: [calendar_with_latlng] or you can also add the near_distance attribute: [calendar_with_latlng near_distance=44].
You would just need to put the above functions into your functions.php, create a Simple Plugin, or save them to a file and add it in your Must-Use Plugins directory.
Of course you can pass a shortcode as an attribute of another shortcode. The only problem is, attributes doesn't pass [ or ]. So you have replace convert those bracket them with their html entry.
Replace [ with [ and ] with ] and you should be fine. Here is an example.
function foo_shortcode( $atts ) {
$a = shortcode_atts( array(
'foo' => "Something",
'bar' => '',
), $atts );
$barContent = html_entity_decode( $atts['bar'] );
$barShortCodeOutput = do_shortcode($barContent);
return sprintf("Foo = %s and bar = %s", $a['foo'], $barShortCodeOutput);
}
add_shortcode( 'foo', 'foo_shortcode' );
function bar_shortcode( $atts ) {
return "Output from bar shortcode";
}
add_shortcode( 'bar', 'bar_shortcode' );
Then put this on your editor
[foo bar=[bar] ]
See we are passing a shortcode [bar] as an attribute of [foo]. So the output should be -
Foo = Something and bar = Output from bar shortcode
I know it looks a bit nasty but it will do the trick.

How to add a link in MediaWiki VisualEditor Toolbar?

I`m trying to insert a custom link to a special page in VisualEditor toolbar. See the image below.
See Image
I googled a lot but without success. Someone please give a path...
My answer is based on the following resources:
MediaWiki core JS doc (ooui-js)
VisualEditor JS doc (+ reading code of both repositories used for VE, mediawiki/extension/VisualEditor and VisualEditor)
Also, I'm pretty sure, that there is no documented way of adding a tool to the toolbar in VE, as far as I know. Although it's possible to add a tool to a group, which is already added, mostly used for the "Insert" tool group, like in Syntaxhighlight_GeSHi). There is, probably, a much easier or "better" way of doing this :)
First, VisualEditor provides a way to load additional modules (called plugins) when the main part of VE loads (mostly, when you click the "Edit" button). The modules needs to be registered via the global variable $wgVisualEditorPluginModules (or the equivalent in extension.json, if you're using the new extension registration). In your extension registration file, you should initialize a module (with your required script files to add the tool) and add it as a VE plugin.
Example PHP (old extension registration via PHP files):
// other setup...
$wgResourceModules['ext.extName.visualeditor'] = array(
'localBasePath' => __DIR__,
'remoteExtPath' => 'extName'
'dependencies' => array(
'ext.visualEditor.mwcore',
),
'scripts' => array(
'javascripts/ve.ui.ExtNameTool.js',
),
'messages' => array(
'extname-ve-toolname',
),
);
$wgVisualEditorPluginModules[] = 'ext.extName.visualeditor';
// other setup...
extension.json (new JSON-based extension registration):
// other setup...
"ResourceModules": {
"ext.geshi.visualEditor": {
"scripts": [
"javascripts/ve.ui.ExtNameTool.js"
],
"dependencies": [
"ext.visualEditor.mwcore"
],
"messages": [
"extname-ve-toolname"
]
}
},
"VisualEditorPluginModules": [
"ext.extName.visualeditor"
],
// other setup...
Now, if VE starts, it will load your module, named ext.extName.visualeditor in this example, with the script ve.ui.ExtNameTool.js. In this script, you can now do, what ever you want. As an example, this is a way to add a new module to the end of the toolgroup list in the toolbar:
Example of ve.ui.ExtNameTool.js:
( function () {
// create a new class, which will inherit ve.ui.Tool,
// which represents one tool
ve.ui.extNameTool = function extNameTool( toolGroup, config ) {
// parent constructor
ve.ui.extNameTool.super.apply( this, arguments );
// the tool should be enabled by default, enable it
this.setDisabled( false );
}
// inherit ve.ui.Tool
OO.inheritClass( ve.ui.extNameTool, ve.ui.Tool );
// every tool needs at least a name, or an icon
// (with the static property icon)
ve.ui.extNameTool.static.name = 'extname';
// don't add the tool to a named group automatically
ve.ui.extNameTool.static.autoAddToGroup = false;
// prevent this tool to be added to a catch-all group (*),
although this tool isn't added to a group
ve.ui.extNameTool.static.autoAddToCatchall = false;
// the title of the group (it's a message key,
// which should be added to the extensions i18n
// en.json file to be translateable)
// can be a string, too
ve.ui.extNameTool.static.title =
OO.ui.deferMsg( 'extname-ve-toolname' );
// onSelect is the handler for a click on the tool
ve.ui.extNameTool.prototype.onSelect = function () {
// show an alert box only, but you can do anything
alert( 'Hello' );
this.setActive( false );
}
// needs to be overwritten, but does nothing so far
ve.ui.extNameTool.prototype.onUpdateState = function () {
ve.ui.extNameTool.super.prototype.onUpdateState.apply( this, arguments );
}
// the tool needs to be registered to the toolFactory
// of the toolbar to be reachable with the given name
ve.ui.toolFactory.register( ve.ui.extNameTool );
// add this tool to the toolbar
ve.init.mw.Target.static.toolbarGroups.push( {
// this will create a new toolgroup with the tools
// named in this include directive. The naem is the name given
// in the static property of the tool
include: [ 'extname' ]
} );
} )();
After installing the extension in your LocalSettings.php and starting VE, you should see a new tool in the toolbar with the given name. Clicking it will show an alert box with content "Hello". Like written in the inline comments: In the click handler (onSelect) you can do whatever you want, e.g. open a link in a new tab, e.g. to a Special page. To get the link to a special page I would suggest to use mw.Title to get a localized namespace. For example:
var relativeUrl = mw.Title.newFromText( 'RecentChanges', -1 ).getUrl();
The first parameter of mw.Title.newFromText() is the name of the page, the second parameter is the ID of the namespace (-1 is the default for special pages and should always work).
I hope that helps!
I am not sure I understand your question entirely. It is as simple as selecting some text, clicking the chain icon, then clicking the External Link tab and pasting your link there.

MediaWiki Extension question / suggestion

Complete beginner here. I want to create a new tab on each page that has a custom action. When clicked, it takes you to a new page which has custom HTML on it along with the text or the original article.
So far I could create a new Tab and could give a custom action mycustomaction to it. I am pasting what I did so far here. Please let me know if I am using the correct hooks etc. and what is a better way to achieve this basic functionality.
So far with their docs I have done this:
#Hook for Tab
$wgHooks['SkinTemplateContentActions'][] = 'myTab';
#Callback
function myTab( $content_actions) {
global $wgTitle;
$content_actions['0'] = array(
'text' => 'my custom label',
'href' => $wgTitle->getFullURL( 'action=mycustomaction' ),
);
return true;
}
#new action hook
$wgHooks['UnknownAction'][] = 'mycustomaction';
#callback
function mycustomaction($action, $article) {
echo $action;
return true;
}
This gives me error:
No such action
The action specified by the URL is invalid. You might have mistyped the URL, or followed an incorrect link. This might also indicate a bug in the software used by yourplugin
What I was doing wrong:
$content_actions[‘0’] should simply be $content_actions[] (minor nitpick)
$content_actions is passed-by-reference, it should be function myTab( &$content_actions ) {}
mycustomaction() should do something along the lines of
if ( $action == ‘mycustomaction’ ) {
do stuff; return false;
}
else {
return true;
}
It should use $wgOut->addHTML() instead of echo
Thanks a lot everyone for your help!

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

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