I am using php framework laravel and I would like to implement shortcodes.
Does anyone have a suggestion how to go about implementing shortcodes that could be inserted by user into a page or blog post.
Example, lets say I would like to have a shortcode for gallery that has some images, something like
[gallery=id]
which would then display that particular gallery. Ofcourse I have gallery model and gallery & images tables.
My first thought is that I would have to scan the content of the page/post and look for shortcode and when I find a particular shortcode, then what? What do I insert instead of it?
I can't insert php code that loops through the gallery and produces output. I guess the best way to do it would be to run a function that returns complete html code that I insert instead of the shortcode.
Is it possible to return a view from a function and insert the result into a page/post?
Depending on what kind of "shortcode" you want, there are numerous options here:
Blade Directives
Blade Layouts
Blade Sub-Views
Blade Stacks
To be clear, I'm assuming you want to insert this into content blocks stored in a db or something, not in your exiting view files.
Assuming you want inject the text into your view for display, you could allow content creators to use a templating format like mustache (https://en.wikipedia.org/wiki/Mustache_%28template_system%29) with server side callbacks/helpers/partials (in the view) to populate your own custom tags with dynamic content (gallery links in this case).
Main Points
I'd stick to a basic well known templating format like
mustache for this. In laravel, allow to Blade templating notation, it sounds like you want for this case to register a Blade::directive: https://www.laravel.com/docs/5.3/blade#service-injection.
I'd try to use an existing library if one such exists before
attempting to create your own short-tagging markup parsing /
callback paradigm. Blade has functions and methods handle such callbacks.
#2 is not necessary, but highly recommended, but #1 should be considered near religious.
UPDATE: as point out in other answers, Laravels built-in templating Blade, has this functionality, so stick to it's format and functionality.
Here's my suggestion (in pseudo-laravel/php):
Assume your marked up content from model pulled into the controller is in $content['blade_markedup_content' => 'here is my new gallery: #gallery(1)'] to be passed to the view.
Add a Blade directive #preprocess() to and in the template/view use <p>#preprocess($blade_markedup_content)</p> in place of just substituting raw <p>{{$blade_markedup_content}}</p>.
In the respective callback function for the #preprocess() directive
Instantiate a new $my_compiler = new BladeCompiler();
Register to this new blade compiler directives to handle the like #gallery(1) you put in your blade_markedup_content
return from the #preprocess() with $my_compiler->compileString($blade_markedup_content);
Viola... In theory, this should result in a parsed and substitute string from #preprocess($blade_markedup_content) in the original template.
Related
Laravel 5.3 introduces a new service called notifications, allowing the construct of emails (among other notifications) via a simple fluent syntax:
return (new MailMessage)
->greeting('Hello!')
->line('One of your invoices has been paid!')
->action('View Invoice', $url)
->line('Thank you for using our application!');
What is an eloquent approach to adding images to the email notifications? I have already published the vendor files to modify the base template.
My thoughts currently stand at:
Extend Illuminate\Notifications\Messages\SimpleMessage as a new local class, along the lines of SimpleMediaMessage with a few additional methods (example: ->image(src, url, alt))
Modify the base template (or create one specific to SimpleMediaMessage that loops over the media array built up via ->image
Finally, register a custom channel to allow notifications to deliver notifications with images.
This seems quite heavy handed for something as simple as images in email. Am I missing something? Is there a better approach?
Edited for clarity
When I refer to images, I mean banner and trail images that are visible in the message itself (not as a seperate attachment).
The attached image shows a) in red what can be currently achieved, and b) in purple what I am looking for.
Second edit
Re-reading the answers posted so far, especially #Erics, I see that with a very simple modification to the template, you can in fact do the following:
->line("<img src='foo.example/bar.jpg' />")
The template needs to be modified to allow unsafe markup:
// Note this is in two spots - intro + outro
{{ $line }} --> becomes --> {!! $line !!}
Disadvantages to this method:
Possibly opening up a security issue, the whole reason of using {{}} over {!!!!}
The image can't take advantage of the inline styles, unless you do it outside the email template, for example:
->line(" < img style='max-width:570px;/* all the other junk to make images look ok in email */' src='foo.example.bar.jpg' /> ")
How are you wanting to attach? In emails you can reference the full path and just add it to the view in typical HTML format:
<img src="http://yoursite.com/path/to/image.png">
If you want to make it a real file attachment there is both an ->attach() and attachData method on the MailMessage. These are typically used for things like PDF's or document attachments.
If you want to attach and reference the attachment in the source then I'm guessing you will need to extend the class like you mentioned or fallback to Laravel's Mail::send method.
Since the notification system was designed to be simple and opinionated I imagine they wanted to cover the common use cases and it's much simpler to use full paths to images versus referencing the cid: style.
As you can see in Mail/resources/html/layout.blade.php, Laravel uses the Markdown notation:
{{ Illuminate\Mail\Markdown::parse($slot) }}
So you can format insert an image using line() method with a code like this:
->line(';
I'm creating a website with CakePHP; the problem now is that I want to show in the website footer (that will be visible on all the pages), the result of a query (e.g. "Most popular products").
What is the correct way with CakePHP to achieve this?
At the moment I created a mostPopularList() in my Product controller and a most-popular-list.ctp view that only outputs an <ul> list, thinking that then I could include the output of this file in my layout (default.ctp), but I didn't find the CakePHP way to do that.
Thanks!
Use a view cell or call the query in the AppControllers beforeRender() callback and set it there to the view. Taken from the documentation:
View cells are small mini-controllers that can invoke view logic and render out templates. They provide a light-weight modular replacement to requestAction(). The idea of cells is borrowed from cells in Ruby, where they fulfill a similar role and purpose.
View Cells
Controller::beforeRender()
If this is needed on really every single page I would probably go for the beforeRender() callback, easy to do and change globally.
I need to insert a URL/button in every article but I need to do this from a specific component, without modifying the existing Joomla components. I need somehow to override the content output and append the necessary elements.
Is this possible?
This is a good place to start - https://docs.joomla.org/Plugin/Events/Content
If you look at the examples it will show you how to write a plugin that can hook into the content a certain point and manipulate it as you see fit using one of the listed functions.
I would put a conditional statement in the hook to find the parameters that match my component and then output my url/button when the condition is matched.
What I'm trying to do is to add some HTML tags to my Djimageslider's slides titles in joomla 2.5. I will need something like this
something <b>more</b>
but when I click on save or apply then its remove all HTML tags.
I've check the administrator/com_content, which I think should be responsible for inserting the database data, but I couldn't find the answer there.
Can anyone help me with this headache?
The form inputs are "cleaned" by default and you want to tell Joomla not to touch its contents.
Find the component you are using in the url (option=com_djsomething?) I doubt it's com_content.
Once you have the component, you have to find where the form is defined.
The task in the url may help, also the view if it's there. The form can be declared in one of two ways:
by providing an xml manifest, which would be located in the component's folder /models/forms
by inserting it in code, which could be in the component's folder /views/view_name (the default view name would be the component's name, but this can be overridden in the controller so look around).
In both cases, you should be able to find the line that corrensponds to your input, and specify format="raw" as a filter.
Check http://docs.joomla.org/Text_form_field_type for syntax help of the xml manifest, or search the docs for the right JElement in code
The format parameter is optional, if it's not there just add it. Besides "raw" there are other filtering options available, make sure you do filter out undesired input and sanitize your inputs before saving to the db (use $db->quote() to insert field values in the query)
I have a prototype website written in PHP. Lately i've rewritten code to separate logic from layout and database operations. So now I have something like MVC code design.
Now what bothers me, is that in MVC I'll have many files and each will display something when combined with other (model+view+controller). So I figured out that it would be usefull to create something like widgets of my MVC parts.
For example when I have MVC of products view than I would create a PHP file that combine MVC part files in such fashion to display products based on GET values I pass to this new PHP file.
What I would acomplish in this way is that any widgets, subparts of website would be available to view separately and use separately from other parts. So it would be something like widgets or like Firefox browser design.
So I would be able to test every part of website separately, and than only combine these parts into current actual website page design. So user testing would be easier too, and the presentation files would be very short and easy to understand.
I would like to know what do you think about it. I don't want to fall into any hole in the design-things and I think that this is the moment that will be important in future to keep maintaining website code easy.
Am I correct?
MVC I'll have many files and each will display something when combined with other (model+view+controller)
This sounds like you didn't get the MVC-model right. Only Views have content or 'display something'.
Based on this, you can create actions which only create a small widget-like part of content, which then can be combined in your Layout.
I'd like to recommend reading the Zend_Layout Quick Start.
The answer to your problem is view composition.
I suggest you splitting the whole screen into smaller pieces: top bar, second-level nav bar, products list, preview area, and so on. These could be provided by separate views, view helpers or additional methods in your controller. Then a controller action would compose pieces into single screen using simplistic HTML layout.
Eg. for top bar that is static this could be specialised view. For products list that is dynamic it could be controller method getProductsList($categoryId) that provides complex view. Product preview can be delivered by view helper. See the following example:
// inside class ProductsController
public function index($categoryId, $productId = null) {
// specialised view
$topBar = new TopBarView();
$topBar->selected = 'products';
// helper method
$list = $this->getProductsList($categoryId);
// helper object
$previewHelper = new PreviewHelper($productId);
$preview = $previewHelper->getView();
// view composition
$view = new View('path/to/template.tpl');
$view->add($topBar);
$view->add($list);
$view->add($preview);
return $view;
}
This is just an example to illustrate how composition works.
Hidden benefit of having method for delivering widget (i.e. products list) is that it could be reused to support Ajax. Changing category would require Ajax call to getProductsList method with new category id.