Change the color of commas in php - php

Here is my code:
<?php
$posttags = get_the_tags();
if ($posttags) {
$tagstrings = array();
foreach($posttags as $tag) {
$tagstrings[] = '' . $tag->name . '';
}
echo implode(', ', $tagstrings);
}
// For an extra touch, use this function instead of `implode` to a better formatted string
// It will return "A, B and C" instead of "A, B, C"
function array_to_string($array, $glue = ', ', $final_glue = ' and ') {
if (1 == count($array)) {
return $array[0];
}
$last_item = array_pop($array);
return implode($glue, $array) . $final_glue . $last_item;
}
?>
The code puts a comma after tags in WP (except the last tag). I would like to change the color of commas. How can I do it?

You can use something like this:
$glue = '<span class="tagglue">,</span> ';
and use that in your implode() calls (either place in your snippet).
Then create a css declaration like:
.tagglue {color: blue;}
Implementation:
<?php
$posttags = get_the_tags();
if ($posttags) {
$tagstrings = array();
foreach($posttags as $tag) {
$tagstrings[] = '' . $tag->name . '';
}
echo array_to_string($tagstrings);
}
// For an extra touch, use this function instead of `implode` to a better formatted string
// It will return "A, B and C" instead of "A, B, C"
function array_to_string($array, $glue = '<span class="tagglue">, </span>', $final_glue = ' and ') {
if (1 == count($array)) {
return $array[0];
}
$last_item = array_pop($array);
return implode($glue, $array) . $final_glue . $last_item;
}
?>
I'll take this change to link several related pages on StackOverflow (that don't offer coloration):
Implode array with ", " and add "and " before last item
Imploding with "and" in the end?
Separate an array with comma and string PHP
implode() an array with multiple database columns, except on last entry PHP
Comma separated list from array with "and" before last element
PHP Add commas to items with AND
Replace the last comma with an & sign
How to replace last comma in string with "and" using php?

Related

Automatically add links to strings of keywords

In my article, I want to automatically add links to keywords.
My keywords array:
$keywords = [
0=>['id'=>1,'slug'=>'getName','url'=>'https://example.com/1'],
1=>['id'=>2,'slug'=>'testName','url'=>'https://example.com/2'],
2=>['id'=>3,'slug'=>'ign','url'=>'https://example.com/3'],
];
This is my code:
private function keywords_replace(string $string, array $key_array)
{
$array_first = $key_array;
$array_last = [];
foreach ($array_first as $key=>$value)
{
$array_last[$key] = [$key, $value['slug'], '<a target="_blank" href="' . $value['url'] . '" title="' . $value['slug'] . '">' . $value['slug'] . '</a>'];
}
$count = count($array_last);
for ($i=0; $i<$count;$i++)
{
for ($j=$count-1;$j>$i;$j--)
{
if (strlen($array_last[$j][1]) > strlen($array_last[$j-1][1]))
{
$tmp = $array_last[$j];
$array_last[$j] = $array_last[$j-1];
$array_last[$j-1] = $tmp;
}
}
}
$keys = $array_last;
foreach ($keys as $key)
{
$string = str_ireplace($key[1],$key[0],$string);
}
foreach ($keys as $key)
{
$string = str_ireplace($key[0],$key[2],$string);
}
return $string;
}
result:
$str = "<p>Just a test: getName testName";
echo $this->keywords_replace($str,$keywords);
like this:Just a test: getName testName
very import: If the string has no spaces, it will not match.Because I will use other languages, sentences will not have spaces like English. Like Wordpress key words auto link
I think my code is not perfect,Is there a better algorithm to implement this function? Thanks!
You can use array_reduce and preg_replace to replace all occurrences of the slug words in your string with the corresponding url values:
$keywords = [
0=>['id'=>1,'slug'=>'getName','url'=>'https://www.getname.com'],
1=>['id'=>2,'slug'=>'testName','url'=>'https://www.testname.com'],
2=>['id'=>3,'slug'=>'ign','url'=>'https://www.ign.com'],
];
$str = "<p>Just a test: getName testName";
echo array_reduce($keywords, function ($c, $v) { return preg_replace('/\\b(' . $v['slug'] . ')\\b/', $v['url'], $c); }, $str);
Output:
<p>Just a test: https://www.getname.com https://www.testname.com
Demo on 3v4l.org
Update
To change the text into links, you need to use this:
echo array_reduce($keywords,
function ($c, $v) {
return preg_replace('/\\b(' . $v['slug'] . ')\\b/',
'$1', $c);
},
$str);
Output:
<p>Just a test: getName testName
Updated demo
Update 2
Because some of the links that are being substituted include words that are also values of slug, it's necessary to do all the replacements at once using the array format of strtr. We build an array of patterns and replacements using array_column, array_combine and array_map, then pass that to strtr:
$reps = array_combine(array_column($keywords, 'slug'),
array_map(function ($k) { return '' . $k['slug'] . ''; }, $keywords
));
$newstr = strtr($str, $reps);
New demo
First you need to change structure of array to key/value using loop that result stored in $newKeywords. Then using preg_replace_callback() select every word in string and check that it exist in key of array. If exist, wrap it in anchor tag.
$newKeywords = [];
foreach ($keywords as $keyword)
$newKeywords[$keyword['slug']] = $keyword['url'];
$newStr = preg_replace_callback("/(\w+)/", function($m) use($newKeywords){
return isset($newKeywords[$m[0]]) ? "<a href='{$newKeywords[$m[0]]}'>{$m[0]}</a>" : $m[0];
}, $str);
Output:
<p>Just a test: <a href='https://www.getname.com'>getName</a> <a href='https://www.testname.com'>testName</a></p>
Check result in demo
My answer uses preg_replace as does Nick's above.
It relies on the patterns and replacements being equally sized arrays, with corresponding patterns and replacements.
Word boundaries need to be respected, which I doubt you can do with a simple string replacement.
<?php
$keywords = [
0=>['id'=>1,'slug'=>'foo','url'=>'https://www.example.com/foo'],
1=>['id'=>2,'slug'=>'bar','url'=>'https://www.example.com/bar'],
2=>['id'=>3,'slug'=>'baz','url'=>'https://www.example.com/baz'],
];
foreach ($keywords as $item)
{
$patterns[] = '#\b(' . $item['slug'] . ')\b#i';
$replacements[] = '$1';
}
$html = "<p>I once knew a barbed man named <i>Foo</i>, he often visited the bar.</p>";
print preg_replace($patterns, $replacements, $html);
Output:
<p>I once knew a barbed man named <i>Foo</i>, he often visited the bar.</p>
This is my answer: thanks for #Nick
$content = array_reduce($keywords , function ($c, $v) {
return preg_replace('/(>[^<>]*?)(' . $v['slug'] . ')([^<>]*?<)/', '$1$2$3', $c);
}, $str);

Function for obtain the first 3 tag names on a post

function hashtags(){
$tags = get_the_tags($post->ID);
$count=0;
foreach ($tags as $tag){
$count++;
if (1 == $count) {
return $tag->name . ', ';
}
if (2 == $count) {
return $tag->name . ', ';
}
if (3 == $count) {
return $tag->name;
}
}
}
I don't know about php, i'm noob, i made this function for showing the name of the first 3 tags of post, i want this return: tag1, tag2, tag3.
The function works but only return the first tag, if i put echo no problem but i don't want an echo, any idea?
Sorry if I've misunderstood but I think you're trying to return a comma separated list of the names found by the get_the_tags function? If so this should work:
$tags = get_the_tags($post->ID);
$names = array();
$count = 1;
foreach ($tags as $tag) {
$names[] = $tag->name;
if ($count++ == 3) {
break;
}
}
return implode(', ', $names);
That code loops through the tags, adds each tag name to an array ($names), and finally runs the array through implode() to generate the comma separated list.

PHP to form string like "A, B, C, and D" from array values

Given the following array:
Array
(
[143] => Car #1
[144] => Car #2
[145] => Car #3
)
I am currently using this
implode(', ', array_values($car_names))
to generate a string like
Car #1, Car #2, Car #3
I would like to actually get something like
Car #1, Car #2 and Car #3
The idea would be to insert " and " between the two last elements of the array.
If the array happens to contain two key/value pairs (eg, user has 2 cars), there would be no commas.
Car #1 and Car #2
And if the array contains one key/value (eg, user has 1 car)
Car #1
Any suggestion how to get this done? I tried using array_splice but I'm not sure that's the way to go (ie, inserting a new element into the array).
Thanks for helping!
$last = array_pop($car_names);
echo implode(', ', $car_names) . ' AND ' . $last;
I think you probably want something like this, using array_pop to get the last element off the end of the array. You can then implode the rest of the array, and add the last element in a custom fashion:
$last_value = array_pop($car_names);
$output = implode(', ', array_values($car_names));
$output .= ($output ? ' and ' : '') . $last_value;
Edit: added conditional to check if the array had only one element.
A preg_replace can look for the last command just just swap it to an and
$yourString = preg_replace( "/, ([\w#]*)$/", "and \1", $yourString );
This solution is a bit longer, but tested for all array sizes and it is a complete solution. Also, it doesn't modify the array like the above answers and is separated into a function.
function arrayToString($arr) {
$count = count($arr);
if ($count <= 2) {
return implode(' and ', $arr);
}
$result = '';
$i = 0;
foreach ($arr as $item) {
if ($i) $result .= ($i == $count - 1) ? ' and ' : ', ';
$result .= $item;
$i++;
}
return $result;
}
Compacted version with ugly formatting and ignoring good practices like initializing variables:
function arrayToString($arr) {
if (count($arr) <= 2) return implode(' and ', $arr);
foreach ($arr as $item) {
if ($i) $result .= ($i == count($arr) - 1) ? ' and ' : ', ';
$result .= $item; $i++;
}
return $result;
}
I'm not sure there's a built in function for this, but something like this should work.
$last = $car_names[count($car_names)-1];
$implodedString = implode(', ', array_values($car_names))
$implodedString = str_replace(", $last", "and $last", $implodedString);
That's an example with the functions named in my comment above:
strrpos() - Find the position of the last occurrence of a substring in a string
substr() - Return part of a string
and the code:
$text = implode(', ', array_values($car_names));
$last = strrpos($text, ',');
if ($last) $text = substr($text, 0, $last-1) . ' AND ' . substr($text, $last+1);
echo $text;
There are a number of ways you could do this. Here's another.
<?php
$cars = array('Car #1', 'Car #2', 'Car #3', 'Car #4');
$car = array('Car #1');
$twocars = array('Car #1', 'Car #2');
function arrayToText($arr) {
switch (count($arr)) {
case 1:
return $arr[0];
break;
case 2:
return implode($arr, ' and ');
break;
default:
$last = array_pop($arr);
return implode($arr, ', ') . ' and ' . $last;
break;
}
}
echo '<p>' . arrayToText($cars) . "</p>\n";
echo '<p>' . arrayToText($twocars) . "</p>\n";
echo '<p>' . arrayToText($car) . "</p>\n";
Output
<p>Car #1, Car #2, Car #3 and Array</p>
<p>Car #1 and Car #2</p>
<p>Car #1</p>

Convert comma separated string into array

I have a comma separated string, which consists of a list of tags and want to convert it to array to get a link for every tag.
Example:
$string = 'html,css,php,mysql,javascript';
I want to make it like this:
html, css, php, mysql, javascript
So the result will be a string containing comma separated links with a space after each link and with no comma after the last link.
I have this function where $arg = 'html,css,php,mysql,javascript':
function info_get_tags( $arg ) {
global $u;
$tagss = '';
if ( $arg == '' ) {
return '';
} else {
$tags_arr = explode( ',' , $arg );
foreach ( $tags_arr as $tag ) {
$tags = '' . $tag . '';
$tagss .= $tags;
}
return $tagss;
}
}
This script works for me but without commas and spaces and if we add a comma and a space here:
$tags = '' . $tag . ', ';
we get commas and spaces but there will be a trailing comma after the last link.
Just like you exploded you can implode again:
$tags = explode(',', $arg);
foreach ($tags as &$tag) {
$tag = '' . $tag . '';
}
return implode(', ', $tags);
Here's an alternative that uses array_map instead of the foreach loop:
global $u;
function add_html($tag){
return('' . $tag . '');
}
function get_tags($taglist){
$tags_arr = array_map("add_html", explode( ',' , $taglist));
return implode(", " , $tags_arr);
}
Try this short code
$string = 'html,css,php,mysql,javascript';
$string = explode(',', $string);
   foreach( $string as $link){
   echo ''.$link.'';
}
Easiest way is to the html into an array (each tag link is an array element) and then implode on ,...
if ( $arg == '' ) {
return '';
} else {
$tags_arr = explode( ',' , $arg );
$tags = array();
$tagtpl = '%s';
foreach ( $tags_arr as $tag ) {
$url = $u . 'tag/' . $tag . '/';
$tags[] = sprintf($tagtpl, $url, $tag, $tag);
}
return implode(', ', $tags);
}
Try this
$tagss = trim($tagss);
return substr($tagss, 0 , strlen($tagss)-1);
Why not put all tags in an array when you are creating them, and later explode the array and add the commas and spaces between the tags.
foreach ( $tags_arr as $tag ) {
$tags = '' . $tag . '';
$tagss[] = $tags;
}
$tagss = explode(', ', $tagss);
The workaround(!) would be to remove the unwanted trailing characters afterwards:
$tagss = rtrim($tagss, ", ");
This rtrim removes any mix of spaces and commas from the right end of the string.
Btw, you could use str_getcsv instead of explode, which also handles input spaces better.
function info_get_tags($arg)
{
global $u;
if (empty($arg)) return '';
return ltrim(preg_replace('/([^\,]+)/', ' ${1}', $arg));
}
$string = 'html,css,php,mysql,javascript';
puts $string.split(/,/).map { |tag| "#{tag}"}.join(", ")
result:
html, css, php, mysql, javascript
Another solution:
$html = trim(preg_replace('/([^,]+)/', ' \1', $string));
Or if you have to html encode the tags (always smart, since you're creating html from text):
$html = trim(preg_replace_callback('/([^,]+)/', function($match) {
$tag = $match[1];
return ' ' . htmlspecialchars($tag) . '';
}, $string));
So this $string would work too: "tag with space,html,css,php,mysql,javascript"
More regex is always good!

Converting line breaks into <li> tags

I'm creating an upload form that has a text area for users to input cooking recipes with. Essentially, what I want to do is wrap each line in a <li> tag for output purposes. I've been trying to manipulate the nl2br function but to no avail. Can anyone help?
I'm retrieving the text area's content via POST and storing entries in a MySQL database.
Here's what the code looks like at the moment (the check_input function strips slashes, etc.):
$prepText=check_input($_POST['preparationText']);
$cookText=check_input($_POST['cookingText']);
Explode the string by \n then wrap each line in an li tag.
<?php
$string = "line 1\nline 2\nline3";
$bits = explode("\n", $string);
$newstring = "<ol>";
foreach($bits as $bit)
{
$newstring .= "<li>" . $bit . "</li>";
}
$newstring .= "</ol>";
Not quite pretty, but an idea that comes to mind is to :
explode the string, using newline as a separator
and implode the array, using </li><li> between items :
Which could be translated to something like this :
$new_string = '<li>' . implode('</li><li>', explode("\n", $old_string)) . '</li>';
(Yeah, bad idea -- don't do that, especially if the text is long)
Another solution, way cleaner, would be to just replace the newlines in your string by </li><li> :
(wrapping the resulting string inside <li> and </li>, to open/close those)
$new_string = '<li>' . str_replace("\n", '</li><li>', $old_string) . '</li>';
With that idea, for example, the following portion of code :
$old_string = <<<STR
this is
an example
of a
string
STR;
$new_string = '<li>' . str_replace("\n", '</li><li>', $old_string) . '</li>';
var_dump($new_string);
Would get you this kind of output :
string '<li>this is</li><li>an example</li><li>of a </li><li>string</li>' (length=64)
I created a function based on Richard's answer in case it saves anyone some time!
/**
* #param string $str - String containing line breaks
* #param string $tag - ul or ol
* #param string $class - classes to add if required
*/
function nl2list($str, $tag = 'ul', $class = '')
{
$bits = explode("\n", $str);
$class_string = $class ? ' class="' . $class . '"' : false;
$newstring = '<' . $tag . $class_string . '>';
foreach ($bits as $bit) {
$newstring .= "<li>" . $bit . "</li>";
}
return $newstring . '</' . $tag . '>';
}
function nl2li($str)
{
if (!isset($str)) return false;
$arr = explode("\r\n", $str);
$li = array_map(function($s){ return '<li>'.$s.'</li>'; }, $arr);
return '<ul>'.implode($li).'</ul>';
}
Input:
Line 1\r\nLine2\r\nLine3\r\n
Output:
<ul><li>Line 1</li><li>Line 2</li><li>Line 3</li></ul>
The simplest way to do it:
function ln2ul($string) {
return '<ul><li>' . str_replace("\n", '</li><li>', trim($string)) . '</li></ul>';
}

Categories