URLEncode in Smarty - smarty

I wrote a Code to short my URL but have Problem during the URL encoding because the URL calls an ID with {$CWunschliste->cURLID}
{php}$short = file_get_contents('http://ur.l/api.php?url=' . urlencode({$ShopURL}/index.php?wlid={$CWunschliste->cURLID}));{/php}
{php}$url=json_decode($short,TRUE);{echo $url['short'];}{/php}
How can I rewrite the url encode to call {$CWunschliste->cURLID} ?

If you use {php} tags in Smarty templates you should place there PHP code, so you cannot use Smarty syntax. Your code should probably look like this:
{php}
$short = file_get_contents('http://ur.l/api.php?url=' . urlencode($this->getTemplateVars('ShopURL').'/index.php?wlid='.$this->getTemplateVars('CWunschliste')->cURLID));
$url=json_decode($short,TRUE);
echo $url['short'];
{/php}
However you shouldn't do it this way. You should do such things in PHP. Smarty is just for displaying views and not for getting data from remote urls or other model tasks.
In addition {php} tag is deprecated and can be used only in SmartyBC class.
EDIT
I forgot to remove { from answer ( already fixed it) but even in this case I got the following error
Using $this when not in object context
That's really strange because if you look at Smarty php tag example in this example $this is used to access Smarty object.
However the working solution would be changing $this into $template ( I have to emphasise $template is in this case not the name of Smarty object created in PHP - I've created Smarty object $smarty but in {php} tags I have to access Smarty using $template).
The following code should work for you:
{php}
$short = file_get_contents('http://ur.l/api.php?url=' . urlencode($template->getTemplateVars('ShopURL').'/index.php?wlid='.$template->getTemplateVars('CWunschliste')->cURLID));
$url=json_decode($short,TRUE);
echo $url['short'];
{/php}

Related

How to display blog post with HTML code snippets in Laravel

My blog posts are saved in a DB in text format and I can't find the way of displaying HTML code between the paragraphs as you can see in the image below.
I'm using Prismjs and <pre><code></code></pre> tags..
Inside the code block there should be two <div> tags which are not displayed.
Looks like this in the database table
Laravel is a web application framework with expressive, elegant syntax. A web framework provides a structure and starting point for creating your application, allowing you to focus on creating something amazing while we sweat the details.
Laravel strives to provide an amazing developer experience while providing powerful features such as thorough dependency injection, an expressive database abstraction layer, queues and scheduled jobs, unit and integration testing, and more.
Whether you are new to PHP or web frameworks or have years of experience, Laravel is a framework that can grow with you. We'll help you take your first steps as a web developer or give you a boost as you take your expertise to the next level. We can't wait to see what you build.
<pre><code class="lang-html">
<div>test</div>
</code></pre>
In my post_body.blade.php view I'm using {!! nl2br($post->body) !!} to display the content of the post.
If I use <pre><code class="lang-html">{{ $post->body }}</code></pre> on the blade view the code is visible but I have no way of including the text of the post. It would only work to show code.
I'm facing the problem of not been able to do both things, is one or the other.
There is no straightforward way of doing this by using standard Laravel/Blade output options. However it's possible to accomplish it with a little bit of extra code.
1. Why is this happening
Neither <pre> or <code> is stopping the browser to interpret the text inside as html code. They have different purpose: one is to tell the browser that the whitespaces are important and the other to tell that the content is some computer code and needs to be shown with different styling. In both cases if valid HTML code is inside the tags it will be treated as HTML.
By the way it's mentioned in Prism documentation that you need to escape the content:
Note: You have to escape all < and & characters inside < code > elements
(code blocks and inline snippets) with < and & respectively, or
else the browser might interpret them as an HTML tag or entity. If you
have large portions of HTML code, you can use the Unescaped Markup
plugin to work around this.
2. Solutions
There are different ways of solving your issue. You can either modify the input before saving it to the database and then just print the unescaped contents or modify the output and make sure you have escaped only the text in the <code> tag.
Because we don't know much about the input method you use let's focus on the second option to modify the output.
A. PrismJS
Their documentation points to a solution where you can use the Unescaped markup plugin to solve your issue. I don't have any experience with it, but the slogan says "Write markup without having to escape anything.", so it seems it will do the work.
You only need to include the plugin and then you have two options: to swap <pre><code> for <script> or to use HTML-comment to wrap your code (if you don't have other comments in the code
Just look at their examples for detailed information
B. PHP
You can use PHP to parse the text from the database and escape the content of the needed elements. In your case this is the code element. You will need to write your own implementation or use the one that I wrote for your case.
Then you can just do:
{!! Houdini::escape($content) !!}
Include or autoload the following class:
class Houdini
{
/**
* Escape the html characters inside a given HTML element
*
* #param string $text The text we are trying to clean
* #param string $element The name of the elements to be escaped
* #param bool $fix Should we try to make the text a valid HTML by wrapping it with divs
*
* #return string
*/
public static function escape($text, $element = 'code', $fix = true) {
$dom = new DOMDocument;
$dom->loadXML($fix ? '<div>' . $text . '</div>' : $text);
$nodes = $dom->getElementsByTagName($element);
foreach ($nodes as $node) {
$content = '';
foreach ($node->childNodes as $child) {
$content .= self::escapeRecursively($child);
}
$node->nodeValue = htmlspecialchars($content);
}
return $dom->saveHTML();
}
/**
* Escape node and note contents
*
* #param $node
* #return string
*/
protected static function escapeRecursively($node) {
if ($node instanceof DOMText)
return $node->textContent;
$content = "<$node->nodeName>";
foreach ($node->childNodes as $child) {
$content .= self::escapeRecursively($child);
}
return "$content</$node->nodeName>";
}
}
C. JavaScript
You can include the following javascript code which will loop trough all the <code> elements and set the innerHtml as the innerText.
document.querySelectorAll("code").forEach(el => el.innerText = el.innerHTML);
Note: If you keep the paragraphs in the database separated only with new lines and not wrapped in <p> you will have issues using this solution and nl2br() together.
D. Deprecated <xmp>
<pre><code class="lang-html">
<xmp><div>test</div></xmp>
</code></pre>
There WAS after all an HTML tag specifically to show example HTML code as it is, but it was deprecated in HTML 3.2, BUT it seems the tag is widely supported and wrapping the code contents can be a quick and dirty solution for your case. You can see the support tables here: https://caniuse.com/?search=xmp
Read more here: https://html.com/tags/xmp/#ixzz74T0AJctF
You can accomplish this by adding the tags before saving to the database or when printing the output with JavaScript on the client side or with PHP before passing it to the blade template.
3. Other StackOverflow posts that helped me for this answer
Escape HTML Chars In the Pre Tag
How to show <div> tag literally in <code>/<pre> tag?

Variable Variable in Smarty Templates

I have a dynamically generated Smarty variable in PHP. I want to access it with name ,
Say for example there is a smarty variable {$asdf} which was generated dynamically and i have an array that has 'asdf' i want to use this array and access {$asdf}.
{$asdf} prints a input element [rendered] ;
$array = array('asdf');
{foreach from=$array item=x}
{$x}
{/foreach}
//but {$x} is not giving renderend input instead it is giving $asdf
where am i going wrong?
It is generally atypical to do this type of work in a template file. You should separate your template and logic as much as possible -- there's no plausible scenario in which you could not simply prepare the needed variables for your template in php and pass them on to the template in a useable structure.
That said, it is possible. Within a template, all variables that were passed to the template are accessible in an array, Smarty::_tpl_vars. Within a template, one may interact with this array using the {php}{/php} tags, where it can be referenced via $this --
{php}
$unknownValue = $this->_tpl_vars[
$this->_tpl_vars['known_key']
];
// for example...
$this->_tpl_vars['magicalValue'] = $unknownValue;
{/php}
Magic: {$magicalValue}
I cannot reiterate enough, however, that it is generally bad practice to place such logic inside a template.

How to enable Auto Complete in PHPStorm for CodeIgniter framework

In CodeIgniter Project, I've normally use following commands to execute sql.
$res = $this->db->select('*')
->from('customer')
->where('customer.id', $id)
->get();
But unfortunatly my PHP Storm(5.0) didn't support multiple autocomplete(I don't know how to say this)
For example in netbeans If I typed
$res = $this->db->select('*')->
It will auto pop up the rest of the function. But In PHPStorm It didn't wokring.
Its working first level auto complete only.
download https://github.com/topdown/phpStorm-CC-Helpers/releases
Mark as Plain Text
/system/core/Controller.php
/system/core/Model.php
/system/database/DB_active_rec.php
Then Extract the downloaded archive, copy it to your project root
That's all
Mifas links do the same too though
Answering to a very old but still pertinent question -
I found a better solution herein - http://validwebs.com/346/code-completion-for-codeigniter-in-phpstorm/ and coincidentally it is from the same author/project owner Jeff Behnke.
Quoting from therein which should be read in continuation of the answer by Sabir -
Mark as Plain Text
/system/core/Controller.php
/system/core/Model.php
/system/database/DB_active_rec.php
Marking those files as plain text stops phpStorm from indexing them as
sources.
I consider the solution in the link better because it explains the rationale behind the steps performed.
It additionally explains how we can achieve code completion in views and fix for undefined vars.
Quoting once again from the original source for easy reference and preservation herein :
Code Completion in Views and fixing undefined vars.
Example controller code.
public function index()
{
// Example view vars
$data['test'] = 'Testing vars in CodeIgniter! This is from $data["test"].';
$this->load->view('welcome_message', $data);
}
We added a data array to the view the CI way. Each index in the array
is another variable.
The view…
In phpStorm $test will be highlighted as an undefined var. To fix this
we use phpDoc annotations.
<p style="font-weight: bold;">
<?php
/**
* $data array holds the $test value
*
* #see Welcome::index()
* #var Welcome $test
*/
echo $test;
?>
</p>
Documenting this way not only fixes the phpStorm error/warning but
also gives us documentation popup for $test. Also the #see will link
to the location it was created, in this case index method in the
Welcome class.
The var is now defined and shows it is.
Ctrl+ Click on this method link will bring you right to the method
where $test is defined.
Herein are a few discoveries of my own while adding customisations to my project:
If you want your custom application libraries from CI to be available for auto-completion as well then there are these 2 scenarios which may be helpful :
1. For custom extended libraries such as MY_Upload extending the CI_Upload class
Replace #property CI_Upload $upload with #property MY_Upload $upload in CI_phpstorm.php
This shall make all the class variable and function names of MY_Upload available for auto-completion in addition to that of CI_Upload.
2. For completely custom libraries written from scratch within the CI application -
For e.g. to enable auto-completion from Custom_Library.php residing in the application/libraries folder, you need to add to the php doc in CI_phpstorm.php #property Custom_Library $custom_library

How to use include function in another custom function?

I am using Smarty 3.1.8
I want to include a tpl file only one time on page even if tpl file called more times.I dont know that I can do the that with Smarty without write a new custom function.So I think to write a new custom include function for this.
Can I use include function of smarty in the custom include function ?
I want to use smarty include function in my the custom include function for compile given template.
How am I do this ?
I want to use as follow :
{include_js file="script.users.tpl"}
Are you using PHP? If, so try this:
Even though it's in Smarty, use the php include_once("/dir/filename"); function.
using smarty_bc or smarty2:
{some_smarty.tpl}
<html>
<p>ex paragraph one</p>
<p>ex paragraph two</p>
{php} include_once("script.users.tpl"); {/php}
</html>
This way you can rely on having PHP monitor that the file is only being inserted once.

Page-specific logic in Joomla

I am trying to enable JavaScript in a Joomla template to behave differently depending on the page. In particular, I have set the Key Reference as that appears to be the most appropriate value I could find for this purpose. Unfortunately, I can't seem to access it in my code. I tried:
$this->params->get("keyref")
and a few other variations, but they simply returned a blank. How can I retrieve this value or is there a better way of writing page specific logic.
Related Articles
Joomla load script in a specific page: This would work, but seems like overkill for what I want to do here.
Each page can be given an alias. We can retrieve the alias using code from the forum:
function getCurrentAlias()
{
$menu = &JSite::getMenu();
$active = $menu->getActive();
return $active->alias;
}
We can then inject this into the Javascript:
var alias= '<?php echo getCurrentAlias(); ?>';
I'm not aware of keyref, but I would solve it by using the class suffix parameter you can set for each menu entry.see I would use a space in front of this suffix. With javascript you can then try to read this classname (suffix without the space) on each page.
getElementsByClassName("mysuffix");
for example
If this returns multiple objects, you know on which page you are. Will that help you?

Resources