I have a hard time to style a link via the Drupal 8 render structure.
This link needs to be displayed in my custom module:
$add_link = \Drupal::l('<i class="fa fa-cog"></i>' . t('Add new project'), $url);
So between de tags I want a Font awesome icon in front of the text.
But Drupal print all html out as readable text.
I also notice that the l() function is deprecated in Drupal 8.
So what is the best way to do this in the Drupal 8 render structure?
If, like me, you wanted to use a render array of #type => 'link' and include an icon with it then you can do the following:
<?php
use Drupal\Core\Render\Markup;
use Drupal\Core\Url;
$form['actions']['reset_password'] = [
'#type' => 'link',
'#title' => Markup::create('<span class="glyphicon glyphicon-cog"></span> Forgot / Reset Password'),
'#url' => Url::fromRoute('user.pass'),
];
Took me a while, but this should work. Your code has a $url variable which may work fine, but this code below also shows how i got my $url.
$url = new Url(
'entity.eab_contact_entity.edit_form', array(
'eab_contact_entity' => $entity->id(),
)
);
$icon_text = $this->t('<i class="fa fa-pencil"></i>');
$edit_link = \Drupal::service('link_generator')->generate($icon_text, $url);
It turns out that any text that goes into a link needs to be 'safe', so that malicious code cannot be injected etc. If you're curious, it was discussed at length here: https://www.drupal.org/node/2273923
The main point, though, and what makes the above code work for me and answers your question, is the $this->t() surrounding the font-awesome string '<i class="fa fa-pencil"></i>'. That renders it 'safe' and the link generated has the HTML we want, rather than just printing out the text of the HTML.
Finally, in case you are looking for help generating your URL, this tutorial has a lot of hints.
Or if you need to pass spectial chars like or any HTML tag in your link title you can also use the following:
$link_text = Markup::create('<div>' . $node->getTitle() . '</div>');
$link = Link::fromTextAndUrl($link_text, $node->toUrl());
Related
I fetch data from a MySQL database, the data stored is this:
<p><script>alert('123');</script><br /></p>
When I fetch the data normally I get this as result:
<script>alert('123');</script>
This is fine and works as expected, however when I fetch the data into a textarea which is initialized with Summernote I get an alert like this:
Somehow Summernote converts the escaped html tags to functioning HTML.
How do I fix this?
I have already tried the answer of this question:
Escaped HTML in summernote
It did not work.
Why are you not sanitising data both at the time of storage, and when displayed in the Editor, or outside of the editor? Typically, in my CMS, I don't allow <script/> tags as way to help mitigate users adding potentially dangerous scripts.
That said, there is a PR that is being discussed about how we can best go about fixing this issue. https://github.com/summernote/summernote/pull/3782 information or help would be greatly appreciated to move it along, or even another PR fixing the issue.
I managed to fix it by instead of fetching the data in the textarea fetching it in via jQuery like this:
<textarea name="description" id="description"></textarea>
<script>
$('#description').summernote({
height: 250,
codeviewFilter: false,
codeviewIframeFilter: true,
// toolbar
toolbar: [
['font', ['bold', 'italic', 'underline', 'clear']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
['view', ['fullscreen', 'codeview', 'help']]
],
}).on("summernote.enter", function(we, e) {
$(this).summernote('pasteHTML', '<br /> ');
e.preventDefault();
});
$("#description").summernote("code", "<?php echo $video->getDetails('', $fileName, 'desc'); ?>");
</script>
Now it doesn't convert > and $lt; to <> if it is the script tag.
See more information here:
https://github.com/summernote/summernote/pull/3782#issuecomment-774432392
Using javascript you can easily fix this. It worked for me in a React + Django project. I also used django_summer_note and it was also showing data like yours. Then I got that solution:
//simply just create a function like this which will return your data (which one you used with django_summernote).
const createBlog = () => {
return { __html: blog.description };
};
// now in your HTML(JSX) show your data like this.
<div className='' dangerouslySetInnerHTML={createBlog()} />
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.
I'm using yii2-imagine
$imagine = yii\imagine\Image::getImagine();
Imagine->open('path/watermark.jpg')->show('jpg');
My problem is it not show the image, it show that:
����JFIF��>CREATOR: gd-jpeg v1.0 (using IJG JPEG v90), default quality ��C $.' ",#(7),01444'9=82<.342��C 2!!22222222222222222222222222222222222222222222222222����"�� ���}!1AQa"q2���#B��R��$3br� %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz��������������������������������������������������������������������������� ���w!1AQaq"2�B���� #3R�br� $4�%�
Any idea?
You need to use the getImagine() function first to invoke the GD or Imagick which ever available instance then call ->open() and ->show() on the object. Moreover, you need to provide the $options for the image to display too. You can copy paste the following code inside an action in your controller and can see the result image. I just tested on my local system, and it is in working, just remember to provide valid path to the $source variable
use yii\imagine\Image;
$source="/path/to/your/image.jpg";
$imagine = new Image();
$options = array(
'resolution-units' => \Imagine\Image\ImageInterface::RESOLUTION_PIXELSPERINCH,
'resolution-x' => 300,
'resolution-y' => 300,
'jpeg_quality' => 100,
);
echo $imagine->getImagine()->open($source)->show('jpg',$options);
Apart from the above solution that displays the image in the browser if you want to display the image inside the img tag you can base64_encode the raw image data returned from the open() method and provide into the tag like below.
echo '<img src="data:image/jpeg;base64,'.base64_encode($imagine->getImagine()->open($source)).'" >';
Hope it helps
I'm having lots of problems with a really poor-developed themeforest WP theme, Dignity.
In particular, I have a short code that renders a custom text rotator. Code is pretty straightforward, something like:
[text-rotator customclass="mycssclass"]my text, my text<br />new text[/text-rotator]
The very odd thing is that when the short code is displayed, every HTML tag is removed. They are directly removed, and the content is not touched. For example, for the code above, I will get in output my text, mytextnewtext; without the line break.
How come? Perhaps is a built-in WP filter? I checked through the short code function, but there seems not to be any filter. Here's where the short code is registered:
function dignity_text_rotator($atts, $content = null)
{
extract(shortcode_atts(array("customclass" => '', "fx" => ''), $atts));
//Options
$data_fx = '';
if($fx != '')
{
$data_fx = 'data-fx="'.$fx.'"';
$customclass = $customclass.' animated';
}
if($customclass != '') { $cc = $customclass; } else $cc = '';
//Return content
$html = '<div class="text-rotator '.$cc.'" '.$data_fx.'><span class="rotate">'.do_shortcode($content).'</span></div>';
return $html;
}
Any hint?
Updated: oddly, the problem was in the js script that then reads the text inside the div and creates the actual text-rotator.
In fact, it sanitizes all the html when reading node html by directly removing the HTML tags. To solve this, I had to modify the way the note content is retrieved in the JS script.
I'm using Perls PDF::FromHTML to create a PDF-file. My code looks like this:
open HTML, ">", "file.html";
...
close HTML;
chmod(0777, "file.html");
my $pdf = PDF::FromHTML->new(encoding => 'utf-8');
$pdf->load_file("file.html") or die $!;
$pdf->convert(
Font => 'Arial',
LineHeight => 10,
Landscape => 1
);
$pdf->write_file("file.pdf") or die $!;
Since I had difficulties creating an actual PDF-file at the beginning, I'm now exactly following the synopsis on cpan, which is
my $pdf = PDF::FromHTML->new( encoding => 'utf-8' );
# Loading from a file:
$pdf->load_file('source.html');
# Perform the actual conversion:
$pdf->convert(
# With PDF::API2, font names such as 'traditional' also works
Font => 'font.ttf',
LineHeight => 10,
Landscape => 1,
);
# Write to a file:
$pdf->write_file('target.pdf');
However this creates a PDF-file at the right location, but it only consists of a white page. The HTML-file is complete and looks like it should look. What am I missing?
You need to specify a valid font. The second example has a non valid fontname.
If you installed PDF::API2 you could try to use: 'Helvetica' as fontname.
Please check you HTML file, it should be quite simple (no CSS or javascript).
Regards,