I am using the standard Content field that is automatically generated by default to add some text.
"Content" => "HTMLText"
If I use a limiting function e.g
$Content.BigSummary(300)
This limits the words but doesn't keep the line breaks. Aka strips the HTML out.
Looking through the framework code, there is ContextSummary()
public function ContextSummary($characters = 500, $string = false, $striphtml = true, $highlight = true,
$prefix = "... ", $suffix = "...")
However upon testing, using this on an HTMLText field doesn't seem to work, it limits the characters but it doesn't keep the HTML unless the field type is Text e.g
HTMLText:
$Content.ContextSummary(200, false, false) - Strips HTML still
Text:
$Content.ContextSummary(200, false, false) - Keeps HTML (Which is what I want)
Am I doing something wrong? Or is there another function I can use to achieve what I want? Or create a custom function?
The issue is with conversion to simple text and back to html - <br> tags are lost as I encountered once. This is a similar hack I used.
// override ContextSummary from the Page_Controller
public function ContextSummary($field = 'Content', $characters = 500, $string = false) {
$content = $this->dbObject($field);
$content->setValue(str_replace('<br>', '__br__', $content->getValue);
$summary = $content->ContextSummary($characters, $string, $stripHtml = false);
return str_replace('__br__', '<br>', $summary);
}
and use $ContextSummary(Content) instead of $Content.ContextSummary in template
Related
Firstly, I created some text values
Text gamecon1 = Text('1v1 Box Fight');
Text gamecon1duo = Text('1v1 Duos');
Text gamecon2 = Text('2v2 Box Fight');
Text gamecon2sq = Text('2v2 Squads');
Text gamecon3 = Text('3v3 Box Fight');
Text gamecon4 = Text('4v4 Box Fight');
Then i queried a document field from firestore and wrote a conditional statement
Text((() {
if (tourneyDetails['tourneyprizes'] ==
gamecon1) {
return multiplier = 8;
} else if (tourneyDetails[
'tourneyprizes'] ==
gamecon1duo) {
return multiplier = 5;
String calculator = (int.parse(
tourneyDetails[
'tourneycost']) *
multiplier)
.toString();
String calculatordivide =
(double.parse(calculator) / 100.0)
.toString();
String calculatorpercentage =
(double.parse(calculatordivide) *
20)
.toString();
String calculatorfinal =
(double.parse(calculator) -
double.parse(
calculatorpercentage))
.toString();
return calculatorfinal;
What i am trying to accomplish is, if the document field is equal to one the text values, then it should run the calculation and return the value.
but this doesn't work.
After some troubleshooting, i realised that even when the text value is the same as the document field queried, flutter still doesn't recognise it.
If you need more context feel free to comment. Thanks
Without knowing what the type definition of tourneyDetails is I cannot be sure but I suspect that you are trying to compare a String (in tourneyDetails) with a Text widget. If so, they will never equate. You should be defining your strings as constants eg. const gamecon1 = '1v1 Box Fight'; then the comparison should equate.
Text() is a widget. You want to compare Strings.
if (tourneyDetails['tourneyprizes'] == gamecon1.data)
or
define String gamecon1 = 'gamecon1' and tourneyDetails must also be an array of Strings.
I have read in a lot of sources that I should use the geofield_compute_values() function when trying to programmatically save coordinates in Drupal.
However it does not work for me, that function is undefined in the Drupal 8.5.2 that I am using.
I've installed geofield using composer and I can use it as usual in the admin area and there are no problems with saving there.
Here are some examples I've tried with, the first example gives me undefined function geofield_compute_values() :
$geofield_data = geofield_compute_values([
'lat' => $lat,
'lon' => $lon,
], GEOFIELD_INPUT_LAT_LON);
$cbisProduct->set('field_koordinater', $geofield_data);
I have also tried this out with no successful result and no errors :
$geofield = [
'geom' => "POINT (" . $lon . " " . $lat . ")",
'geo_type' => 'point',
'lat' => $lat,
'lon' => $lon,
'left' => $lon,
'top' => $lat,
'right' => $lon,
'bottom' => $lat,
];
$cbisProduct->set('field_koordinater', $geofield);
Seems like you're trying to use the geofield_compute_values() function which was available in 7.x version, but not in 8.x
You should look into the wkt_generator service. i.e.
<?php $wktGenerator = \Drupal::service('geofield.wkt_generator'); ?>
I haven't tried this, but something like this should work:
<?php
$point = [
'lat' => $request->get('lat'),
'lon' => $request->get('lon'),
];
$value = \Drupal::service('geofield.wkt_generator')->WktBuildPoint($point);
$node->field_koordinater->setValue($value);
Also, WktGeneratorTest.php and GeofieldItemTest.php files could be a good start to see how to use the service in your implementation.
This function is not available in Drupal 8. You have to rely on the basic GeofieldItem class that extends FieldItemBase. Also, as mentioned by oman, you can use WktGenerator to easily build points, polygons, etc.
Here a working example. Let's say your have an entity $cbisProduct with a multivalued geofield field_koordinater, and you want to set the first item with arbitrary lat/lon coordinates :
// Get geofield item
$geofield = $cbisProduct->get('field_koordinater')->get(0);
// Generate a point [lat, lon]
$coord = ['45.909621', '6.127147'];
$point = \Drupal::service('geofield.wkt_generator')->WktBuildPoint($coord);
// Calling this function will compute values AND assign geodata to the field instance
$geofield->setValue($point);
// You can read the computed geodata from the field
$geodata = $geofield->getValue();
//dpm($geodata);
// Explicitly set field data (needed if $geofield is not a reference)
$cbisProduct->set('field_koordinater', [$geodata]);
// Save entity
$cbisProduct->save();
Under the hood, GeofieldItem::setValue calls another method responsible to directly assign the computed values to the field instance :
# \Drupal\geofield\Plugin\Field\FieldType\GeofieldItem
protected function populateComputedValues() {
/* #var \Geometry $geom */
$geom = \Drupal::service('geofield.geophp')->load($this->value);
if (!empty($geom)) {
/* #var \Point $centroid */
$centroid = $geom->getCentroid();
$bounding = $geom->getBBox();
$this->geo_type = $geom->geometryType();
$this->lon = $centroid->getX();
$this->lat = $centroid->getY();
$this->left = $bounding['minx'];
$this->top = $bounding['maxy'];
$this->right = $bounding['maxx'];
$this->bottom = $bounding['miny'];
$this->geohash = substr($geom->out('geohash'), 0, GEOFIELD_GEOHASH_LENGTH);
$this->latlon = $centroid->getY() . ',' . $centroid->getX();
}
}
Note : You don't necessarily need WktGenerator for building points, as long as you know the geofield type and how geophp should handle it. For example, the following 2 statements are equivalent :
$point = \Drupal::service('geofield.wkt_generator')->WktBuildPoint($coord);
// is equivalent to
$point = GEOFIELD_TYPE_POINT . '(' . implode(' ', $coord) . ')');
But it is safer to rely on the WktGenerator especially with more complex data types.
For each post, there is a custom field name "Function", the key/value pair is like this:
Key : Functions
Value : <!--en-->Nourishing Yin and invigorating the vital essence of kidneys.<!--:--><!--tw-->滋陰補腎。<!--:-->
The problem is if I simply use get_post_meta , it return string of both language, how can I get the value based on the language?
I am using qTranslate right now, Thanks.
Updated (the code):
$custom_fields = get_post_custom(get_the_ID());
$function = get_post_custom_values('Functions', get_the_ID());
You can simply fetch the strings considering comments as prefix and suffix -
After you get the custom field value,
e.g.
$function = "<!--en-->Nourishing Yin and invigorating the vital essence of kidneys.<!--:--><!--tw-->滋陰補腎。<!--:-->";
$arr = explode("<!--:-->", $function);
$new_arr = array();
foreach($arr as $a ){
if(!empty($a)){
$lang = str_replace( "-->", "", substr($a, 4, 5) );
$str = substr($a, 9);
$new_arr[$lang] = $str;
}
}
Now $new_arr will have key/value pairs like array(language_code => sentence).
If you do print_r($new_arr);
It will give output as follows:
Array ( [en] => Nourishing Yin and invigorating the vital essence of kidneys. [tw] => 滋陰補腎。 )
Now you can identify the strings using their respective language codes.
In Symfony 2, I am using the translation:update command to generate translations YML files from my templates where I already have defined teh translation strings.
I get .yml files where everything is mixed up.
I am searching for a tool, a script that could refactor this :
menu.home: __en.menu.home
menu.projects: __en.menu.projects
information.address: __en.information.address
information.agent.languages.english: __en.information.agent.languages.english
information.agent.languages.russian: __en.information.agent.languages.russian
information.agent.name: __en.information.agent.name
to :
information:
address: __en.information.address
agent:
languages:
english: __en.information.agent.languages.english
russian: __en.information.agent.languages.russian
name: __en.information.agent.name
menu:
home: __en.menu.home
projects: __en.menu.projects
Here is a code snippet to do what you ask:
use Symfony\Component\Yaml\Yaml;
use Symfony\Component\Yaml\Dumper;
// ...
$dottedYaml = Yaml::parse(file_get_contents('dotted-file.yml'));
$nestedYaml = array();
foreach ($dottedYaml as $dottedKey => $value) {
$levels = explode('.', $dottedKey);
$levelYaml =& $nestedYaml;
do {
$level = array_shift($levels);
if (!isset($levelYaml[$level])) {
$levelYaml[$level] = array();
}
$levelYaml =& $levelYaml[$level];
} while (count($levels));
$levelYaml = $value;
}
$dumper = new Dumper();
file_put_contents('nested-file.yml', $dumper->dump($nestedYaml, 5));
Please be aware that even though my code works for your example if you have something like this:
menu: "here is the problem"
menu.home: __en.menu.home
menu.projects: __en.menu.projects
You cannot actually convert to a nested notation unless you decide some kind of convention if a certain level contains a scalar value AND an array of nested values:
menu:
home: __en.menu.home
projects: __en.menu.projects
value: "here is the problem" # we made up a "value" attribute to store the top level value
I have five custom fields for loading images but all of them are not required. I mean the user can upload a random number of images from 1 to 5. I am stuck in a simple lack of concept here. How should I check if any of them is empty and discard it. More specifically I want to discard the non-existing fields and store only the uploaded ones in an array. Here is my code
$custom_fields = get_post_custom($id);
$my_custom_field1 = $custom_fields['image1'];
$my_custom_field2 = $custom_fields['image2'];
$my_custom_field3 = $custom_fields['image3'];
$my_custom_field4 = $custom_fields['image4'];
$my_custom_field5 = $custom_fields['image5'];
if(!(false===($my_custom_field1))) { $img[]=$my_custom_field1;}
if(!(false===($my_custom_field2))) { $img[]=$my_custom_field2;}
if(!(false===($my_custom_field3))) { $img[]=$my_custom_field3;}
if(!(false===($my_custom_field4))) { $img[]=$my_custom_field4;}
if(!(false===($my_custom_field5))) { $img[]=$my_custom_field5;}
$images = Array("image1","image2","image3","image4","image5");
foreach($images as $image){
if(isset($custom_fields[$image])){
$img[] = $custom_fields[$image];
}
}
Didn't tested that, but should work.
if(isset($my_custom_field5)){
// do something with $my_custom_field5
}
I would suggest using
if ( !empty($my_custom_field)){
\\Do Something
}
because isset only checks for variable beings set and not null where as empty checks if the variable is an empty string, false, array(), NULL, “0?, 0, and an unset variable.