As i have gone through the documentation provided by Phalcon for Volt Templating Engine. I found addFuntion() to add custom function in Volt Compiler to customize data. But regarding n-level hierarchical menu / catalog case, i need recursion in addFunction() which i am unable to make it work. Please guide me a solution for this.
No problem in using recursion - remember that volt is compiled to PHP files. Also volt functions are plain PHP so:
$compiler->addFunction(
'menu',
function ($resolvedArgs, $exprArgs) {
return 'MenuHelper::menu(' . $resolvedArgs . ')';
}
);
Then why not:
class MenuHelper
{
public static function menu($data)
{
if (empty($data)) {
return '';
}
$out = '<ul>';
foreach ($data as $name => $children) {
$out .= '<li>' . $name . self::menu($children) . '</li>';
}
$out .= '</ul>';
return $out;
}
}
And view.volt:
{{ menu([ 'a' : [ 'a1' : [], 'a1' : ['a11' : [],'a12' : [],'a13' : [] ] ], 'b' : [] ]) }}
Will give you:
<ul><li>a<ul><li>a1<ul><li>a11</li><li>a12</li><li>a13</li></ul></li></ul></li><li>b</li></ul>
Related
I'm working on WordPress actually and created a plugin from scratch, fully working on admin page.
The plugin allow you to add country and languages related (USA->English|Sapnish for example)
I am using Class and constructor for the plugin's functions
Now I would like to created a select with country and depending on country another select with languages. I know how to create this in js/html but I can't find a way to get the data from the plugin.
I tried :
Create a function (in the plugin) who used plugin's other functions (see below)
public function getCountry()
{
global $wpdb;
$table_name = $wpdb->prefix . "country_wmu";
$results = $wpdb->get_results('SELECT * FROM ' . $table_name);
if ($wpdb->last_error !== '') {
echo '<p class="info-wmu error">Une erreur est survenue</p>';
} else {
return $results;
}
}
public function getLang($id)
{
global $wpdb;
$table_name = $wpdb->prefix . "lang_wmu";
$results = $wpdb->get_results('SELECT * FROM ' . $table_name . ' WHERE _id_country = ' . $id);
if ($wpdb->last_error !== '') {
echo '<p class="info-wmu error">Une erreur est survenue</p>';
} else {
return $results;
}
}
public function wmu_get_data($atts, $content=null)
{
$country = $this->getCountry();
foreach ($country as $key => $value) {
$country_id = $value->id;
$lang = $this->getLang($country_id);
foreach ($lang as $key2 => $value2) {
$country[$key]->lang = array(
'name' => $value2->name,
'url' => $value2->url
);
}
}
return $country;
}
and then add shortcode
add_shortcode('wmu_data', 'wmu_get_data');
and displaying the shortcode in the page, but shortcode displays as plain text
[wmu_data]
So I tried to do a function in my functions.php to do a do_shortcode, then add a shortcode to this function.
function test()
{
$country = do_shortcode('[wmu_data]');
echo '<pre>';
print_r($country);
echo '</pre>';
}
add_shortcode('test','test');
But nothing happens, blank page...
I really don't have many more ideas to do it...
EDIT:
I found out with the error code, Have to use
add_shortcode('wmu_data', array('WB_MultiLang_URL','wmu_data'));
to call it outside the function
thanks Larjos for pointing out the problem at his root :)
I need to know if it's possible how to get_the_tags() to array?
i want to like this
$myarray = array('one', 'two', 'three', 'four', 'five', 'six');
i want use this code with "replace the_content" like this
<?php
function replace_content($content){
foreach(get_the_tags() as $tag) {
$out .= $tag->name .',';
$csv_tags .= '"' . $tag->name . '"';
}
$find = array($out);
$replace = array($csv_tags);
$content = str_replace($find, $replace, $content);
return $content;
}
add_filter('the_content', 'replace_content');
?>
find tag in content and replace with link
$posttags = get_the_tags();
$my_array = array();
if ($posttags) {
foreach($posttags as $tag) {
$my_array[] = $tag->name ;
}
.. and if your final goal is to output it like you wrote above then :
echo implode(',', $my_array);
.. and by the type of question , I was not sure if by one,two.. you might be meaning ID , so :
$posttags = get_the_tags();
$my_array = array();
if ($posttags) {
foreach($posttags as $tag) {
$my_array[] = $tag->term_id ;
}
BTW - a quick look at the codex would have shown you that ...
You should be able to do something like this:
global $wpdb;
// get all term names in an indexed array
$array = $wpdb->get_results("SELECT name FROM wp_terms", ARRAY_N);
// walk over the array, use a anonymous function as callback
array_walk($array, function(&$item, $key) { $item = "'".$item[0]."'"; });
Notice that anonymous functions are only available since PHP 5.3
You should be able to do the same thing using get_the_tags() if you only want tags for a specific post:
$tags = get_the_tags();
array_walk($tags, function(&$item, $key) { $item = "'".$item->name."'"; });
Judging from your updated question you don't need any of the above code, the only thing you need to to in order to get single quotes around each tag is:
foreach(get_the_tags() as $tag) {
$out .= $tag->name . ',';
$csv_tags .= '"' . "'".$tag->name."'" . '"';
}
I want to add title="icons/icon_cart.gif" for each of the below options in my select list which is rendered using views.
After trying and reading many articles I can't seem to find the way to add this html into my form.
Below is my code.
function customchatter_form_alter(&$form, &$form_state, $form_id) {
$form["tid"]["#options"][1]=t("nooo chatter");
// this works to change the label of the option but how do I add title="icons/icon-
cart.gif" ?
}
My html code:
<select id="edit-tid" name="tid" class="form-select">
<option value="All">- Any -</option>
<option value="1">nooo chatter</option>
<option value="2">Complaints Complaints</option>
<option value="3">Gear & Gadgets</option>
</select>
Cheers,
Vishal
UPDATE
I tried to update the code as per Clive's advice but the values are still not coming up right. Below is my story.
So below is the html output I am able to achieve but the title always seems to be the number 1.
<select id="edit-select" class="form-select" name="select">
<option value="1" title="1">One</option>
<option value="2" title="1">Two</option>
</select>
As you can see title is there but the value is wrong. Below is my form and the functions which I wrote.
My form:
$form['select'] = array(
'#type' => 'select',
'#options' => array(1 => 'One', 2 => 'Two'),
'#title' => array(1 => 'One', 2 => 'Two')
// I tried many combinations but nothing seems to work.
);
My Theme functions.
function kt_vusers_select($variables) {
$element = $variables['element'];
element_set_attributes($element, array('id', 'name', 'size'));
_form_set_class($element, array('form-select'));
return '<select' . drupal_attributes($element['#attributes']) . '>' .
kt_vusers_form_select_options($element) . '</select>';
}
function kt_vusers_form_select_options($element, $choices = NULL) {
if (!isset($choices)) {
$choices = $element['#options'];
}
// array_key_exists() accommodates the rare event where $element['#value'] is NULL.
// isset() fails in this situation.
$value_valid = isset($element['#value']) || array_key_exists('#value', $element);
// #vishal so there I have declared the variable to accept the values.
$vtitle = isset($element['#title']) || array_key_exists('#title', $element);
$value_is_array = $value_valid && is_array($element['#value']);
$options = '';
foreach ($choices as $key => $choice) {
if (is_array($choice)) {
$options .= '<optgroup label="' . $key . '">';
$options .= form_select_options($element, $choice);
$options .= '</optgroup>';
}
elseif (is_object($choice)) {
$options .= form_select_options($element, $choice->option);
}
else {
$key = (string) $key;
if ($value_valid && (!$value_is_array && (string) $element['#value'] === $key ||
($value_is_array && in_array($key, $element['#value'])))) {
$selected = ' selected="selected"';
}
else {
$selected = '';
}
// #vishal this is where the variable is being used.
$options .= '<option title="'.$vtitle.'" value="' . check_plain($key) . '"' . $selected .
'>' . check_plain($choice) . '</option>';
}
}
return $options;
}
below is the correct code for the last theme function
function kt_vusers_form_select_options($element, $choices = NULL, $vtitles=NULL) {
// Build up your own version of form_select_options here
// that takes into account your extra attribute needs.
// This will probably involve inspecting your custom FAPI property,
// which we'll call #extra_option_attributes
if (!isset($choices)) {
$choices = $element['#options'];
$vtitles = array();
$vtitles = $element['#title'];
}
// array_key_exists() accommodates the rare event where $element['#value'] is NULL.
// isset() fails in this situation.
$value_valid = isset($element['#value']) || array_key_exists('#value', $element);
$value_is_array = $value_valid && is_array($element['#value']);
$options = '';
// print_r($vtitles);
while
(
(list($key, $choice) = each($choices))
&& (list($keytwo, $vtitle) = each($vtitles))
)
{
// printf("%s => %s, %s => %s \n", $key1, $value1, $key2, $value2);
if (is_array($choice)) {
$options .= '<optgroup label="' . $key . '">';
$options .= kt_vusers_form_select_options($element, $choice);
$i++;
// $options .= form_select_options($element, $vtitle);
$options .= '</optgroup>';
} // end if if is_array
elseif(is_object($choice)) {
$options .= form_select_options($element, $choice->option);
} // end of else if
else {
$key = (string) $key;
if ($value_valid && (!$value_is_array && (string) $element['#value'] === $key ||
($value_is_array && in_array($key, $element['#value'])))) {
$selected = ' selected="selected"';
}
else {
$selected = '';
}
// $options .= '<option title="'.$vtitle.'" value="' . check_plain($key) . '"' .
$selected . '>' . check_plain($choice) . '</option>';
}
$options .= '<option value="'. check_plain($key) .'" title="' . $vtitle . '"' . $selected
.'>'. check_plain($choice) .'</option>';
} // end of choice
return $options;
} // end of function
I'm afraid you're going to have to dig quite far down to do this, the #options array is flattened in form_select_options() and it doesn't currently include any way of adding attributes. This is the code:
$options .= '<option value="' . check_plain($key) . '"' . $selected . '>' . check_plain($choice) . '</option>';
As you can see there's simply no scope for attributes in there. You will be able to override this though, but it will involve implementing your own version of theme_select() and your own FAPI property.
I haven't got time to flesh the entire thing out but in your theme file you would be doing something like this:
function MYTHEME_select($variables) {
$element = $variables['element'];
element_set_attributes($element, array('id', 'name', 'size'));
_form_set_class($element, array('form-select'));
return '<select' . drupal_attributes($element['#attributes']) . '>' . MYTHEME_form_select_options($element) . '</select>';
}
function MYTHEME_form_select_options($element) {
// Build up your own version of form_select_options here
// that takes into account your extra attribute needs.
// This will probably involve inspecting your custom FAPI property,
// which we'll call #extra_option_attributes
}
Refer to form_select_options for constructing MYTHEME_form_select_options
And your code in the form would be something like:
$form['select'] = array(
'#type' => 'select',
'#options' => array(1 => 'One', 2 => 'Two'),
'#extra_option_attributes' => array(
1 => array('title' => 'Test title'), // Attributes for option with key "1",
2 => array('title' => 'Test title'), // Attributes for option with key "2",
)
);
In MYTHEME_form_select_options() you can then inspect the element's #extra_option_attributes key (if one exists) to see if you need to physically add any more attributes in the HTML you create.
Hope that helps, I know it seems like a crazily long-winded way of doing what you need to but as far as I know it's the only way.
Tested
Try:
$form["tid"][1]['#attributes'] = array('title' => t('nooo chatter'));
instead of:
$form["tid"]['#options'][1]['#attributes'] = array('title' => t('nooo chatter'));
It is possible to add arbitrary attributes to elements this way. I discovered this after performing some tests based on this answer.
Also mentioned here and here.
Untested, but have you tried:
$form["tid"]["#options"][1]['#attributes'] = array('title' => t('YOUR NEW TITLE'));
You might need to mess around with the name of the element etc but the #attributes tag should work.
EDIT: As pointed out in Clive's answer, this won't work but I'll leave it up in case anyone wants to know how to add attributes to other fields (textboxes etc).
Hello i have a website and a blog, i want to display my self hosted wordpress blog on my website.
I want to show only 3 post on my website.
I want to automatically check for any new post everytime when i reload my website, so that the recent three gets displayed only.
I want to show the complete title of my wordpress blogpost but specific letters of description.
Also the description should end up with a word not some piece of non-dictionary word ending with "..."
How this can be done, i have heard that it can be done through RSS.
Can somebody help me?
To accomplish this you need to read the RSS of the blog, from RSS you need to read the Title and the description, after reading the whole description and title you need to trim the description to your desired number of letters. After that you need to check weather the description last word has been completed or not and then you need to remove a the last word if not completed and put the "...".
First we will make a script to trim the description and to put "..." in last:-
<?php
global $text, $maxchar, $end;
function substrwords($text, $maxchar, $end='...') {
if (strlen($text) > $maxchar || $text == '') {
$words = preg_split('/\s/', $text);
$output = '';
$i = 0;
while (1) {
$length = strlen($output)+strlen($words[$i]);
if ($length > $maxchar) {
break;
}
else {
$output .= " " . $words[$i];
++$i;
}
}
$output .= $end;
}
else {
$output = $text;
}
return $output;
}
Now we will define the variables in which we store the values:-
$xml=("http://your-blog-path/rss/");
global $item_title, $item_link, $item_description;
$xmlDoc = new DOMDocument();
$xmlDoc->load($xml);
$x=$xmlDoc->getElementsByTagName('item');
Now, we will make an array and store values in it. I am only taking 3 because you have asked it the way. You can change it to anything (The number of post you want to show, put that in the loop)
for ($i=0; $i<3; $i++)
{
$item_title[$i] = $x->item($i)->getElementsByTagName('title')->item(0)->childNodes->item(0)->nodeValue;
$item_link[$i] = $x->item($i)->getElementsByTagName('link')->item(0)->childNodes->item(0)->nodeValue;
$item_description[$i] = $x->item($i)->getElementsByTagName('description')->item(0)->childNodes->item(0)->nodeValue;
}
?>
Now echo all these values, Link is the value where your user will click and he will be taken to your blog:-
FIRST RECENT POST:
<?php echo $item_title[0]; ?>
<?php echo substrwords($item_description[0],70); ?>
SECOND RECENT POST:
<?php echo $item_title[1]; ?>
<?php echo substrwords($item_description[1],70); ?>
THIRD RECENT POST:
<?php echo $item_title[2]; ?>
<?php echo substrwords($item_description[2],70); ?>
Hope this can solve your problem. By the way Nice question.
Click here for the original documentation on displaying RSS feeds with PHP.
Django Anonymous's substrwords function is being used to trim the description and to insert the ... at the end of the description if the it passes the $maxchar value.
Full Code:
blog.php
<?php
global $text, $maxchar, $end;
function substrwords($text, $maxchar, $end='...') {
if (strlen($text) > $maxchar || $text == '') {
$words = preg_split('/\s/', $text);
$output = '';
$i = 0;
while (1) {
$length = strlen($output)+strlen($words[$i]);
if ($length > $maxchar) {
break;
} else {
$output .= " " . $words[$i];
++$i;
}
}
$output .= $end;
} else {
$output = $text;
}
return $output;
}
$rss = new DOMDocument();
$rss->load('http://wordpress.org/news/feed/'); // <-- Change feed to your site
$feed = array();
foreach ($rss->getElementsByTagName('item') as $node) {
$item = array (
'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
'desc' => $node->getElementsByTagName('description')->item(0)->nodeValue,
'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
'date' => $node->getElementsByTagName('pubDate')->item(0)->nodeValue,
);
array_push($feed, $item);
}
$limit = 3; // <-- Change the number of posts shown
for ($x=0; $x<$limit; $x++) {
$title = str_replace(' & ', ' & ', $feed[$x]['title']);
$link = $feed[$x]['link'];
$description = $feed[$x]['desc'];
$description = substrwords($description, 100);
$date = date('l F d, Y', strtotime($feed[$x]['date']));
echo '<p><strong>'.$title.'</strong><br />';
echo '<small><em>Posted on '.$date.'</em></small></p>';
echo '<p>'.$description.'</p>';
}
?>
You can easily put this in a separate PHP file (blog.php) and call it inside your actual page.
Example:
social.php
<h3>Latest blog post:</h3>
<?php require 'blog.php' ?>
Also, this code is plug-n-play friendly.
Why not use the Wordpress REST API to retrieve posts -
API URL is : https://public-api.wordpress.com/rest/v1/sites/$site/posts/
where $site is the site id of your wordpress blog
or else simply use this plugin -
http://www.codehandling.com/2013/07/wordpress-feeds-on-your-website-with.html
When submitting a message in my site-wide contact form in Drupal 6.x I get the following message along the top of every message:
[Name] sent a message using the contact form at [www.mysite.com/contact]
I would like to remove this message. Looking around, I've found it comes from the contact.module here:
$message['body'][] = t("!name sent a message using the contact form at !form.", array('!name' => $params['name'], '!form' => url($_GET['q'], array('absolute' => TRUE, 'language' => $language))), $language->language);
I've done a bit of research and it seems that I need to create a custom module with a hook_mail_alter() function to edit the contact.module. When it comes to this I get a bit lost. Could anyone kindly take me through the steps to accomplish the task?
Many thanks.
I did something like that recently. Here is a template you can use to get what you need. Most is from the contact module. The code below is from Drupal 7 but should work as is in Drupal 6.
/**
* Implementation of hook_mail_alter().
*/
function modulename_mail_alter(&$message) {
if ($message['id'] == 'contact_page_mail') {
$language = $message['language'];
$params = $message['params'];
$variables = array(
'!form-url' => url($_GET['q'], array('absolute' => TRUE, 'language' => $language)),
'!sender-name' => format_username($params['sender']),
'!sender-url' => $params['sender']->uid ? url('user/' . $params['sender']->uid, array('absolute' => TRUE, 'language' => $language)) : $params['sender']->mail,
);
$message['body'] = array();
$message['body'][] = t("Your custom message with variables", $variables, array('langcode' => $language->language));
$message['body'][] = $params['message']; // Append the user's message/
}
}
function theme_mail_alter(&$message) {
// only alter contact forms
if (!empty($message['id']) && $message['id'] == 'contact_page_mail') {
$contact_message = $message['params']['contact_message'];
$message['body'] = [];
$fields = $contact_message->getFields();
$new_body .= 'Message:' . PHP_EOL . $contact_message->get('message')->value . PHP_EOL . PHP_EOL;
foreach ($fields as $field_name => $field) {
if (get_class($field->getFieldDefinition()) == 'Drupal\field\Entity\FieldConfig') {
$new_body .= $field->getFieldDefinition()->label() . ':' . PHP_EOL;
if (isset($contact_message->get($field_name)->entity->uri->value)) {
$uri = $contact_message->get($field_name)->entity->uri->value;
$url = file_create_url($uri);
$new_body .= $url . PHP_EOL . PHP_EOL;
} else {
$new_body .= $contact_message->get($field_name)->value . PHP_EOL . PHP_EOL;
}
}
}
$message['body'][] = $new_body;
}
}