Wordpress suggest with key value pair in admin - php

I have a meta box in which there is a text box that grabs the list of custom post type's title. So far its working fine but the problem is that i don't find a way to implement key/value autocomplete using wordpress built-in suggest plugin. Here is my code
/**
* Return list of artists for autocomplete. .
*
* #since 1.0.0
*/
public function list_artists() {
// This only send the post titles not the id
foreach($result as $k => $v) {
echo $v . "\n";
}
// This doesn't work and sends the whole text as json string
$results = array(1 => 'Raheel', 2 => 'Zain', 3 => 'Vicky');
echo json_encode($results);
die();
}
/**
* Provide a dashboard view for the plugin
*
* This file is used to markup the public-facing aspects of the plugin.
*
* #link http://example.com
* #since 1.0.0
*
* #package Songs_Cloud
* #subpackage Songs_Cloud/admin/partials
*/
function show_album_meta_box() { ?>
<label for="artist">Artist</label>
<input type="text" id="artist" name="artist">
<script type="text/javascript">
jQuery(function($) {
$("#artist").suggest(ajaxurl + "?action=sc_list_artists", { delay: 500, minchars: 2 });
});
</script>
<?php }
I am not willing to use dropdown because there can be 1000s for artists and it won't look good in the admin section.
Is there any possibility to achieve this using suggest plugin or any other approach that i can use ?

I think i should utilize Select2
That way i will just bind the dropdown dynamically and load the select2 plugin so that it give a nice interface to the admin section rather the long dropdown list.

Related

Is there a way to have $args suggestions when using a template part?

I work in a WP project using template parts, as they are multiple buttons instance in this project i created a button template that can take multiple arguments as such:
<?
/**
* Default button template
*
*/
$container_classes = $args["container_classes"]; //additional container classes
$button_type = $args['button_type']; // link | button | modal
$elem_classes = $args['elem_classes']; //additional classes for the button
$url = $args['url'] ?? null; //provides the url target
$text = $args['text'] ?? null; // text to display inside the button
$text_color = $args['text_color'] ?? "white"; // text color
$bg_color = $args['bg_color'] ?? 'cta';
$target = $args['target'] ?? "_self"; //target attribute
$icon = $args['icon'] ?? null; //If there is an icon, link to the icon
$modal_slug = $args['modal_slug'] ?? 'null'
?>
<div class="button-<?= $button_type ?> flex <?= $container_classes ?>">
{... All the button specifications and other logical checks ... }
</div>
I would now like to use this template in multiple sections. But with all those $args i would like to have suggestions when typing in the arguments in the get_template_part() function.
Is there a way of defining the possible $args in the template-part file as i've seen it being used in functions for instance ?
Exemple of predefined params for a function:
function get_template_part( $slug, $name = null, $args = array() ) {
/**
* Fires before the specified template part file is loaded.
*
* The dynamic portion of the hook name, `$slug`, refers to the slug name
* for the generic template part.
*
* #since 3.0.0
* #since 5.5.0 The `$args` parameter was added.
*
* #param string $slug The slug name for the generic template.
* #param string|null $name The name of the specialized template.
* #param array $args Additional arguments passed to the template.
*/
where the #param notation defines expected parameters.
I'm trying to have suggestion proposed by VsCode when using a template part and trying to figure out a way for the $args to reproduce the params behavior in the case of a function.

Wordpress add_filter 'template_include' not working

My code is:
<?php
/**
* Plugin Name: xxxxxxxxxxxx
* Plugin URI: https://xxxxxxxxxxxxx.com
* Description: xxxxxxxxxx
* Version: 2020/05/01
* Author: xxxxxxxxxxxxxxx
* Author URI: https://xxxxxxxxxxxxx.com
*/
error_reporting(E_ERROR | E_PARSE);
function ss_replace_text($page)
{
return $page;
}
add_filter('template_include', 'ss_replace');
function ss_replace()
{
ob_start();
ob_start('ss_replace_text');
}
It returns nothing, it should return the page content to the browser.
You should have a look at how output buffers work in PHP ob-start reference
Then, you also need to understand how filters work. They basically take an argument ( which is the output ) send it to the filter and the filter needs to return ( not echo ) the modified output This is a good reference
Then, make sure that 'template_include' is the actual filter you want to use. That is usually used for loading a different file based on some conditions. I never used it for changing the output of the loaded file. template_include filter reference
The code should look something like this:
add_filter('template_include', 'ss_replace');
function ss_replace( $template )
{
ob_start('ss_replace_text');
echo $template;
return ob_get_clean();
}

How can I Overwrite PHP file in Wordpress?

I am customizing the following theme.
https://github.com/inc2734/snow-monkey
And I'd like to add font - weight 300 to noto sans.
https://github.com/inc2734/snow-monkey/blob/9c817ca3c5176101db23185838260e2739163ebe/resources/src/css/foundation/_body/_body.php
"enqueue_noto_sans_jp.php" consists of the following code, only font-weight 400 is loaded.
<?php
/**
* #package mimizuku
* #author inc2734
* #license GPL-2.0+
*/
namespace Inc2734\Mimizuku_Core\Helper;
/**
* Enqueue Noto Sans JP
*
* #return void
*/
function enqueue_noto_sans_jp() {
wp_enqueue_style(
'noto-sans-jp',
'https://fonts.googleapis.com/css?family=Noto+Sans+JP&subset=japanese',
[],
wp_get_theme()->get( 'Version' )
);
}
I tried changing "enqueue_noto_sans_jp.php" directly as follows, but it was returned to the original timing at the most.
function enqueue_noto_sans_jp() {
wp_enqueue_style(
'noto-sans-jp',
'https://fonts.googleapis.com/css?family=Noto+Sans+JP:300,500,700&subset=japanese',
[],
wp_get_theme()->get( 'Version' )
);
}
Can I overwrite this with functions.php of the child theme?
Thanks your Help.
John,
Looks like you're on the right track using a child theme, but you only need to change the css part to load in your other fonts and apply css to the page to make use of them.
There is a really good guide to doing that here: https://nudgethemes.com/wordpress-how-to-change-your-theme-font/

Need help with joomla 1.6 module custom basic settings?

I am writing an integration module for our product to go into any Joomla 1.6 page. I need some help with getting custom data (from the API) into the basic settings part but can't seem to find a way to get it.
If you look at the documentation for the creation of a module, the settings for your module you set up in an XML format. That leaves you to hard code any values or selections without any dynamic options whatsoever. Basically what I want to do is setup a very basic module that takes three basic properties:
URL (used to define the path to the API)
API key (The API key)
List selection (Connects to the API and gets list names from your account.)
The list selection would change for every user's API key naturally but because you setup the module with an XML file I see no way around the hard coding of list selection options.
Please tell me if you can build a dynamic <select> with options in a Joomla 1.6 module.
NOTE: I say 1.6 because there is a major difference between 1.5 and 1.6 development in Joomla.
Well after a hell of a struggle and no help here whatsoever I can finally say that I have done it. Here is the process for any googlers in the future:
To build a dynamic dropdown you have to do a bunch of thing right for it to be pulled together by Joomla finally.
Also remember to read the documentation carefully, This answer's methods are not contained in it but maybe someone will wake up and put it there someday.
So after inspection of how the 1.6 architecture puts module variables together using the XML build file here we go.
The XML will look something like this :
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" version="1.6.0" client="site">
<name>...</name>
<author>...</author>
<creationDate>April 2011</creationDate>
<copyright>Copyright (C) 2011 ... All rights reserved.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>...</authorEmail>
<authorUrl>...</authorUrl>
<version>1.6.0</version>
<description>
...
</description>
<files>
<filename module="mod_your_mod">mod_your_mod.php</filename>
<filename>helper.php</filename>
<filename>index.html</filename>
<folder>tmpl</folder>
<folder>elements</folder>
<folder>lib</folder>
</files>
<languages />
<help />
<config>
<fields name="params">
<fieldset name="basic">
<!-- Custom field, list selection from API -->
<!-- Path to module external parameters -->
<field addfieldpath="/modules/mod_your_mod/elements"
name="mod_your_mod_id_selection" <!-- Name of variable -->
type="lists" <!-- New variable type -->
default=""
label="Select lists"
description="This is the list selection, where you select the list a contact can subscribe to." />
</fieldset>
<fieldset
name="advanced">
<field
name="layout"
type="modulelayout"
label="JFIELD_ALT_LAYOUT_LABEL"
description="JFIELD_ALT_MODULE_LAYOUT_DESC" />
<field
name="moduleclass_sfx"
type="text"
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
description="COM_MODULES_FIELD_MODULECLASS_SFX_DESC" />
<field
name="cache"
type="list"
default="1"
label="COM_MODULES_FIELD_CACHING_LABEL"
description="COM_MODULES_FIELD_CACHING_DESC">
<option
value="1">JGLOBAL_USE_GLOBAL</option>
<option
value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
</field>
<field
name="cache_time"
type="text"
default="900"
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
description="COM_MODULES_FIELD_CACHE_TIME_DESC" />
<field
name="cachemode"
type="hidden"
default="itemid">
<option value="itemid"></option>
</field>
</fieldset>
</fields>
</config>
</extension>
So after following the Joomla way of implementing a module here and here, I added the new parameter variable type into the elements folder as lists.php, see the name is the same as the type you declared in the XML file.
The class inside of this file looks like this :
<?php
// No direct access
defined('_JEXEC') or die('Direct Access to this location is not allowed.');
jimport('joomla.html.html');
//import the necessary class definition for formfield
jimport('joomla.form.formfield');
// Include API utility file
require_once(dirname(__FILE__) . '/../lib/your_api.php');
class JFormFieldLists extends JFormField
{
/**
* The form field type.
*
* #var string
* #since 1.6
*/
protected $type = 'lists'; //the form field type see the name is the same
/**
* Method to retrieve the lists that resides in your application using the API.
*
* #return array The field option objects.
* #since 1.6
*/
protected function getInput()
{
$options = array();
$attr = '';
$attr .= ' multiple="multiple"';
$attr .= ' style="width:220px;height:220px;"';
// Get the database instance
$db = JFactory::getDbo();
// Build the select query
$query = 'SELECT params FROM jos_modules'
. ' WHERE module="mod_your_mod"';
$db->setQuery($query);
$params = $db->loadObjectList();
// Decode the options to get thje api key and url
$options = json_decode($params[0]->params, true);
// Gracefully catch empty fields
if ( empty($options['api_key']) === true )
{
$tmp = JHtml::_(
'select.option',
0,
'No lists available, please add an API key'
);
$lists[] = $tmp;
// The dropdown output, return empty list if no API key specified
return JHTML::_(
'select.genericlist',
$lists,
$this->name,
trim($attr),
'value',
'text',
$this->value,
$this->id
);
}
if ( empty($options['url']) === true )
{
$tmp = JHtml::_(
'select.option',
0,
'No lists available, please add the enterprise URL'
);
$lists[] = $tmp;
// The dropdown output, return empty list if no API key specified
return JHTML::_(
'select.genericlist',
$lists,
$this->name,
trim($attr),
'value',
'text',
$this->value,
$this->id
);
}
// Create a new API utility class
$api = new APIClass(
$options['url'],
$options['api_key']
);
try
{
// Get the lists needed for subscription
$response = $api->getLists();
}
catch ( Exception $e )
{
$tmp = JHtml::_(
'select.option',
0,
'Could not connect to the API'
);
$lists[] = $tmp;
// The dropdown output, return empty list if no API key specified
return JHTML::_(
'select.genericlist',
$lists,
$this->name,
trim($attr),
'value',
'text',
$this->value,
$this->id
);
}
$lists = array();
// Builds the options for the dropdown
foreach ( $response['data'] as $list )
{
// Build options object here
$tmp = JHtml::_(
'select.option',
$list['list_id'],
$list['list_name']
);
$lists[] = $tmp;
}
// The dropdown output
/* The name of the select box MUST be the same as in the XML file otherwise
* saving your selection using Joomla will NOT work. Also if you want to make it
* multiple selects don't forget the [].
*/
return JHTML::_(
'select.genericlist',
$lists,
'jform[params][mod_your_mod_id_selection][]',
trim($attr),
'value',
'text',
$this->value,
$this->id
);
}
}
?>
So you will know when everything is working because your selection of the drop down list, built by the API(hence completely dynamic), will save into the module database entry with the name of the select box which you can easily retrieve by calling:
$api_key = $params->get('api_key', '');
in your module file. In this case its called mod_your_mod.php.
I really hope that this helps you when defining customized parameters in the back end of your Joomla 1.6 modules. This allows for extreme customizations and integrates tightly with whatever application you like to use's API.
The only downside is that it might be slow, but using a bunch of checks it fails gracefully when the API is down or not pulling data through correctly. All in all a very unpleasant CMS to work with but that is only my opinion.
There is also a much simpler solution if your needs are basic: http://docs.joomla.org/SQL_form_field_type
There is an "sql" form field type:
<field name="title" type="sql" default="10" label="Select an article" query="SELECT id AS value, title FROM #__content" />
(I sympathize with your frustration - the documentation is terrible, scattered and hard to find)

need some tips on Drupal $form value

I got dpm($form) working. Nice! This is much better way to view data. I am still trying to figure out where stuff is coming from eg: location longitude & latitude. The word 'longitude' is referenced in 20 different places. I thought this was a likely place to isolate text box for this input field. dpm($form['#field_info']['field_store_latitude']['location_settings']['form']['fields']);
Any tips on how to track down individual input elements?
** this is not an answer, but a supplement to my first question **
hi googletorp -
I am trying to modify existing forms using hook_form_alter.
After several hours of poking around, I can now turn off location (longitude/latitude) section of a form like this:
unset($form['field_store_latitude']);
However, turning off just the latitude like this, does not work:
unset($form['field_store_latitude']['0']['#location_settings']['form']['fields']['locpick']);
I cannot find a easy way to link id and names in html source with arrays produced by Krumo.
In this case id is called "edit-field-store-latitude-0-locpick-user-latitude".
I need a recipe or guidelines for identifying form elemets in Drupal form.
I think I nailed down a solution
<?php
// allows you to alter locations fields, which are tricky to access.
// this will require a patch in location module described here:
// http://drupal.org/node/381458#comment-1287362
/**
* Implementation of custom _element_alert() hook.
*/
function form_overrides_location_element_alter(&$element){
// change some location descriptions
$element['locpick']['user_latitude']['#description'] = ' ' . t('Use decimal notation.');
$element['locpick']['user_longitude']['#description'] = ' ' . t('See <a href=!url target=_blank>our help page</a> for more information.', array('!url' => url('latlon_help')));
// or make them disappear entirely
unset($element['locpick']['user_longitude']);
unset($element['locpick']['user_latitude']);
}
/**
* Implementation of form_alter hook.
*/
function form_overrides_form_alter(&$form, $form_state, $form_id) {
switch ($form_id) {
case 'user_profile_form':
// change titles in user profile form
$form['account']['name']['#title'] = t('Login Name');
$form['account']['mail']['#title'] = t('Email');
break;
case 'retailer_node_form':
// let's check what is supposed to be here...
print '<pre>';
//print_r($form);
dsm($form);
print '</pre>';
// this works to remove the city
unset($form['field_myvar_latitude']['0']['#location_settings']['form']['fields']['city']);
// let's try #after_build property
$form['#after_build'][]='mymodule_after_build_mynode';
break;
}
}
function mymodule_after_build_mynode($form, $form_values) {
// This will not work for locations fields
return $form;
}`enter code here`
So there is sneaky way to alter the location field, what you need to do is to use the #after_built callback:
/**
* Implements hook_form_alter().
*/
function mymodule_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'x_node_form') {
// alter the location field
if (isset($form['locations'])) {
$form['locations']['#after_build'][] = 'mymodule_alter_location_field';
}
}
}
/**
* Remove the delete checkbox from location element.
*/
function mymodule_alter_location_field($form_element, &$form_state) {
$location = $form_element[0]; // The location field which you can alter
return $form_element;
}

Categories