CakePHP: is it possible to use model data in layouts? - php

I would like to display a ticker on each page what scrolls some of the latest datas in it. I think to put in the layout file would be more simply if I can read the model data from the layout.
Is it possible?
Or does layout code has access to the variables generated by a controller and passed to a view?
Or is it the only way to make an element and place it inside each view?

Pretty hard to understand what you're asking but i think it's something along the lines of
"How do I make a variable or dataset available to all views globally in CakePHP"
If so it's probabaly worth looking at the app_controller.php file (book.cakephp.org/view/829/The-App-Controller) and the method startUp() you could run a query and assign it using $this->set('ticker', $sql_result);

Perhaps what you need is an element.

And to answer the question : Yes, layout files have access to the variables set to the view in the controller, just like the views and the elements does.

Related

how to implement shortcodes in pages or blog?

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.

CakePHP: How to show the same query data in all my views, directly in the layout file

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.

ModX revo 2.2x: How to use a TV value to set tpl?

I'm trying to figure out a way to render a resource with a specific tpl based on a template variable(tv) value. here is my use case:
I have setup a modx installation for a basic site with a homepage and a blog (I used the articles add-on). I want to display blog posts on the home page, outside of the articles container. From my experience the easiest way to do this is with getResource. However for this specific project I would like to change the tpl of the getResources results based on whatever the tv value is for each result.
The template variable can be looked at as a "post type". if you choose "text" it would have tplA, if you choose "multimedia" it would have tplB etc...
now based on my research you would use the properties 'tplCondition' and 'conditionalTpls' to achieve this in your getResources call, something like this:
[[getResources?
&tplCondition=`tv.blogPostType`
&conditionalTpls=`{"1":"tplA","2":"tplB","3":"tplC"}`
&tpl=`defaultTpl`
]]
The problem is, this does not seem to work with template variables :( it even says it only uses resource fields in the documentation.....which is a REAL bummer, as i have no idea to pull this off otherwise. Based on my limited knowledge, you can maybe create a snippet or something that does this, But i have no clue.
Does anyone have an elegant solution to this problem?
to sum up what im trying to do, again:
-assign a "post type" to blog posts in my articles container via template variable.
-use the template variable value to set a specific tpl based on that value.
any help is highly appreciated. thanks
EDIT: okay I got a reply on the forums and have come across a"solution" to this.
you can accomplish this with css. in the tpl, you do something like:
<article class="[[+tv.post-type]]">....</article>
this will output the post type selected in the tv as the actual element class used, and you can then use css to give the output different looks based on the tv. its actually so simple im a little embarrased i didnt see it before. In my situation it 100% solves my problem, however if you needed to chasnge html im guessing javascript would need to be involved or another method with php. just leaving this here in case someone needs it!
If you need to do major changes to the html you could still probably solve it with css if you have a nice markup. However if thats not enough i would solve it by using one tpl for the getresources call, and letting that tpl handle the switching. If you could have your TV output the value symbolize the name of the tpl that should be used in each case, your tpl would only need this:
[[$[[+tv.yourtv]]]]
Your tv will be evaluated first, and then it will be processed as a chunk. That way you dont need a nasty switch or if-clause.
This is assumin you want toally different tpls, and not just need to change some small part of the standard tpl, in that case you could still use this tecnique though!
Conditional templates seem to work fine with pdoResources (part of pdoTools). (I have to put "tv." in front of the TV in the tplCondition but not in the other TVs)
James is correct.
[[pdoResources?
&includeTVs=`blogPostType`
&tplCondition=`tv.blogPostType`
&conditionalTpls=`{"1":"tplA","2":"tplB","3":"tplC"}`
&tpl=`defaultTpl`
]]

Render one view inside another in cakephp

i have a comments section that gets called at 3 place in one place along with posts and at other two places solo.(comments only). Now using this as a element makes sense. But my posts are also rendered via a element. Does it makes sense to render a element inside another
Here is the answer:
// Render the element in /View/Elements/ajaxreturn.ctp
$this->render('/Elements/ajaxreturn');
http://book.cakephp.org/2.0/en/controllers.html
There's nothing wrong with doing this. No clashes are going to occur as the variables are scoped
http://book.cakephp.org/view/1081/Elements
Since version 2.1 you may embed one view into another by "Extending Views"
$this->extend('/Common/view');
(documentation)
Since I knew about the elements I try to use whenever I can. They help you to minimize the code repetition. It's not unusual include elements inside another.
In fact, I use the same structure in the elements directory as the views directory to organize them.
I assume that the 3 places you mention are handled by views no? So if you have a posts element and a comments element you can include the elements needs according to the view no? In one view you only use the comments element and in the other you only use both elements what do you think?

How can I separate logic and presentation code when building a calendar?

Ok, we have a page. A very simple one. Let's call it page.php. It will have a controller and a view. The controller will just catch up some GET variables and print them out in the beginning of that page, the view will show up an header a footer and a paragraph that will contain the GET variables from the controller.
Now let's imagine we want to add a calendar. You think it's good and easy. Well, it seems not at all to me.
The calendar is made up of <table><tbody>X</tbody></table> which is pure HTML and a logic PHP script (that will fill the X) that will create (based on the time()stamp of the current date and time) the month dates and and numbers.
Now I encounter an ethic problem: How could I divide logic and view of that calendar?
The block of code that will create the dates will print <td> and <tr> elaborating the time(). But if the logic prints HTML isn't it bad? I think so, because you loose that comfortably think called "division of logic and view" that is typical of the MVC pattern.
At the same time if we take all the calendar logic to the controller and we just send to the view and array of dates (with coordinates X and Y to tell him the place where to put the first date of the month) the view will still need of elaborate the array and will became logic as well.
How could I really divide logic and view from this calendar?
Simply iterating over an array in a view is perfectly fine and not a violation of the MVC pattern. The logic happens in the controller where you populate the array. Even better would probably be to put the logic into a Model named Calendar.php and simply initialize it in the controller to pass it to the view.
u can put logic codes in a php file and assign the result to the variables that will show in view file (for example array)
in view file you can echo the variables and put html tags easily.

Categories