Using components in admin-generator modules, it's possible? how? - symfony1

I need to build a admin interface like this image show. In the past I use components for that purpose but now because the modules are generated trough admin-generator I don't know how to get this done. I check all this docs 1, 2, 3 but without any clue on how to do this. I also created a components.class.php under modules/sdriving_empresa/actions folder and include the component in the view include_component('sdriving_empresa') but get this error:
sfComponents initialization failed.
Any help?

Tabs and Partials, the easy way :)
One of the best possible javascripts for that purpose is Javascript Tabifier. Its easy
to install and play with it. You will find a lot of other Javascript and jQuery Tabbers, get the one you most like.
I would advise you to learn everything about symfony 1 partials in order to get the job easily done. Usually partials are a piece of code which is saved in an external file, and does is loaded later in any part of your code. Its like a variable with a lot of html and php code. Partials (the external files) allow also to receive input variables, so its easy to send them ids from related modules or tables.
Lets look at an example with Tabifier with two Tabs, information and Admin and two partials
editSuccess.php
$sModuleName = sfContext::getInstance()->getModuleName();
$sbasepathtabs = $sModuleName . '/tabs';
<div class='tabber' id='tabberglobal1'>
<div class='tabbertab' title='Information' >
<?php
include_partial($sbasepathtabs . '/_information/_information', array('form' => $form));
?>
</div>
<div class="tabbertab" title="Admin" >
<?php
include_partial($sbasepathtabs . '/_admin/_admin', array('form' => $form));
?>
</div>
</div>
Easily setup it:
Inside your module template folder, create the folder: /_tabs
Inside the folder /_tabs create the folder /_information and /_admin
Inside the folder /_tabs/_information create the file partial: _information.php
Inside the folder /_tabs/_admin create the file partial: _admin.php
Inside each one of those files partials write anything you want.
Those partials will receive the left variable form: array('form' => $form).
You can send to the partials more than one variable: array('form' => $form, 'variable2' => $formnumber2)
When you write a partial, in example the partial _information, you can easily get the form object and its values in the template with:
$id = $form->getObject()->getId();
For normal variables you wont need to call getObject.
Finally, take a deep look at the documentation of both things, symfony partials and Javascript Tabifier. They will solve you anything you need.
Backend Admin Generator:
Admin generator automatically generates all templates in the cache folder. Example:
cache\backend\prod\modules\autoTbPrueba1Backend\templates
cache\backend\prod\modules\autoTbPrueba1Backend\templates\indexSuccess.php
Most of its files are already partials, pay attention to the files who has the _ symbol in their name, they are partials. This means that most of the work is already done for you, and the only thing you will have to do is to override some of the partials (TbPrueba1Backend/list_header which is the file _list_header.php) or even the full template (indexSuccess.php) with the extended information you need.
In order to override backend generated templates and partials, you can copy those files to the template folder of your module:
apps\backend\modules\TbPrueba1Backend\templates
apps\backend\modules\TbPrueba1Backend\templates\indexSuccess.php
Set there any additional information you need, and if you dont see anything new while refreshing the web, remember to clear the symfony cache (symfony cc).
Once you have override the the templates and partials with the new information, the only thing you need now is to write/add those partials inside the div tabs created by your bootstrap framework as I described above.
For a good explanation of the admin generator:
Symfony 1.4 change admin generator actions or templates
http://www.slideshare.net/loalf/symfony-y-admin-generator
http://symfony.com/legacy/doc/jobeet/1_4/en/12?orm=Doctrine

You need the moduleName and the componentName in your include_component()
function include_component($moduleName, $componentName, $vars = array())
{
echo get_component($moduleName, $componentName, $vars);
}
Or maybe your module is in the wrong application. In that case, you may consider moving it in a plugin

Related

Can I make a partial template that have readonly fields when used by show and not when used by edit and create?

I've partial templates that are used by the show, edit and create form.
In the show-form I don't want them editable, it can be confusing for the user.
Is there a simple solution for this otherwise I need a different template for the show-form or... why use a template then.
I've tied this and created 2 scripts, one that disables and one that enables.
Script 1.
$(document).ready(function(){
$('.elements').attr('readonly',true);
$('.elements').prop('disabled',true);
});
Script 2.
$(document).ready(function(){
$('.elements').attr('readonly',false);
$('.elements').prop('disabled',false);
});
Then I stored those scripts in assets\javascript.
It worked good in show but both edit and create went read-only too.
It seems like everything that is put in this directory is automatically used in each form, because even though I removed the call from the forms, it was working.
Here I show where I originally added the script-call:
<asset:javascript src="myScript_1.js"/>
</body>
</html>
I was going to add it as a comment but then it started to get long and complicated to follow.
why store it in assets ?
simply add a function block to the templates that need it
_template1.gsp
<script>
$(document).ready(function(){
setReadOnly('${someDefinition}')
function setReadOnly(value) {
if (value==='READONLY') {
$('.elements').attr('readonly',true).prop('disabled',true);
}
}
})
</script>
If this function needs to be shared by a bunch of pages, you could add it to an assets / javascript file but rather than declare it in application.js call the js file <asset:javascript tags specificially on each page
and maybe a variable that you pass to template to say when it should be called
or put that above template1 as a master template and call in each of the other templates that needs the js file (So many options)
Now on the main controller doing action
def MyController {
def view() {
String mode='READONLY'
render view: 'index', model:[instance:params,mode:mode]
}
}
the in index.gsp
if js is there then it will pick up mode and set readonly for that controller action or pass that from one template to another, the controller does not have to define actual mode, the main master view page or index page could define mode too
Maybe you need to play/understand then implement you can't rush these things otherwise you will end up wasting time and rewriting
Just to ensure we are on the same page.
By default the application.js file in the javascript folder has a tree line enabled - this by default then reads in all js files. If you wish to manually call js in different places you will need to remove this line and declare each and every js file that you use like the other lines provided in that file.
So that is the price to pay (no more auto loading js files) until declared in application.js
But then most importantly as you have noticed these are global js functions and really nothing new should be going in there that hasn't got a function something() { } a function call.
They will then react when the actual function is called rather than how you had it which was open for call from any old page since it happened as documents opened regardless

How to create my own layout template and divide it in header.phtml, content and footer.phml? Zf2

I'm learning Zend Framework 2 and walked already through the famous Album tutorial. So I've a basic understanding what’s going on but unfortunately I miss a fundamental part about layouts.
I want to build a basic Web application that supposed to have:
A homepage for guests
A complete different hompage for logged in user
Divide the layout in header, content, footer
I've installed the ZF2 Skeleton Application and the Zfcuser module. The site and registration pages show up like they supposed to.
I'll find all layout files in Application/view and the configured path in Application/config/module.config.php
But I have still a couple of questions:
How can I divide the layout into header, content, footer? (Different templates)
How can I create my own layout.phtml? Is it best practice to overwrite the one in Application/view or should I create my own module that overwrites the complete view_manager array?
How can I load a different layout according a user is logged in or not? The zfcUser module provides an helper for that:
if(!$this->zfcUserIdentity()):
But I don't know where to add it.
Thank you so much in advance. And if anyone has a good link to a tutorial - please post it. I really appreciate it.
For dividing layout template into blocks, you can use Partial view helper (zf2 docs), simple example of layout template:
<html>
<body>
<?php
// render template from view/partials/header.phtml
echo $this->partial('partials/header');
?>
<?php echo $this->content; ?>
<?php
// render template from view/partials/footer.phtml with some additional variables from layout scope
echo $this->partial('partials/footer', [
'variable' => 'value',
]);
?>
</body>
</html>
If it should be new different layout template, just create new one in view/layout path of your module and use it like I showed you above (layout controller plugin).
If you want overwrite layout template (or any other template) from 3rd party module, you can do it in ViewManager config (zf2 docs), example with overwriting login template from ZfcUser module:
// module.config.php
'view_manager' => [
'template_map' => [
'zfc-user/user/login' => '/path/to/custom/login-template',
],
],
There is Layout controller plugin (zf2 docs), which allows you changing the layout per controller action. For example, in your home page controller action, you can set different layout for for logged users, like this:
if($this->zfcUserIdentity()) {
$this->layout('layout/members');
}
Definitely take a look at this (incomplete) ZF2 Quick Start rewrite with some best practices.

Using the lib folder for application parts in rails

there are some problems with Ruby on Rails I couldn't solve even spending hours and hours trying. I hope you guys can help me. The four questions are marked with Q1-Q4 at beginning of line.
I have an element in the view that I need more than once. For this reason there should be a separate module in the lib folder (so I can use it in an other project too).
What I need:
- A helper method that I can call automatically from any view.
- Since it requires more html stuff, I want to use an html file, which I render in the helper-method.
- Pass parameters to a javascript file.
- If the element is used, the JavaScript file must be included
- If the element is used, the CSS file must be included
Since it isn't easy to understand what I mean, I'll explain it again with a simple example (it's just an example, so don't think to much about its sence): Helper for creating a combo box with a view-helper or alternatively with a javascript method.
Clearly, I need
(html) - a text input field placed on top of a drop down box
(js) - a function that displays the selected item of the drop-down box in the text box.
(css) - the style of the text box positioned in front of the drop down.
(settings) - a settings file that initializes the element so that I can use it everywhere automatically.
The folder structure which I imagine:
lib
combo_box
combo_box_helper.rb
_combo_box.html.erb
combo_box.js
combo_box.css
At the combo_box-helper.rb I have 2 Methods:
combo_box_field(drop_down_content)
The method gives back a combobox using the partial. The array entries are available in the drop down box.
combo_box_js(drop_down_content)
The method must be called when a combo box is to be created using javascript. To make changes to the combobox only once, the element should also be created with the partial and passed to javascript.
Here appear the first problem:
Q1: At the first call (and only on the first call) of any method, it have to include the js and css file. What is the common way to do this?
Q2: How can I render a partial that is located in the lib folder and not in the app/view folder?
Q3: What is the common way to pass parameters to javascript?
My first try:
module ComboBoxHelper
def combo_box_field(drop_down_content)
output = check_first_call
output + render(:partial => 'combo_box', :locals => {:content => drop_down_content})
end
def
output = check_first_call
output + "<div class='hidden' data-combobox = '" + render(:partial => 'combo_box', :locals => {:content => drop_down_content}) + "'></div>"
end
def check_first_call
if #already_called
""
else
#already_called = true
javascript_include_tag("combo_box.js") + stylesheet_link_tag("combo_box.css")
end
end
end
Problems:
render-method doesn't work (it searches in app/view for the partial)
the call of check_first_call is ugly. especially as it returns a string.
the includes of javascript and css don't work (the files aren't in the asset pipeline)
The content of the .html.erb and .css files is self-explanatory.
Interesting part of the javascript file is my attempt to access parameters passed by Ruby on Rails:
$('div.hidden[data-combobox]').data("combobox")
If these problems are solved, only one thing is important:
How do I initialize the module correctly, so I use it automatically everywhere.
My first try:
I create a file at the folder config/initializers/init_combo_box with that code:
require_dependency 'combo_box/combo_box_helper'
ActiveSupport.on_load(:action_view) do
include ComboBoxHelper
end
Q4: Is this the common way? Do I have something to add to solve one of the above problems (for example the add the js- and css-files to the asset pipeline)?
Thanks for your help.

Adding content to static files(pages)

I have several static files(pages), which are basically copies of my website pages source code, with the content changed.
These files support my website, (keeping the same format) in various ways.
For example the menu part is:-
<body>
<div id="menu">
<ul class="level1" id="root">
etc
etc. until
</ul>
</div>
Unfortunately every month or so my menu bar changes and I have to update each static file manually.
As each of my static files have the same menu.
Is it possible to have one menu file which can be updated and have the static files load them automatically.
I plan to have several more static files. So this would be a great help if someone can suggest how to accomplish this.
Oh yes. Use some javascript magic to load the menu bar upon page load and keep it in menu.html.
One solution may be to use a spider (wget --recursive) to download generated pages directly from your application. One command, and you have the full copy of your site. (just add some useful options, like --convert-links, for example).
The other option may be to write an after_filter in your controller, and write the generated content to a file (not always, but for example when you add a parameter ?refresh_copy=1). Maybe just turning on page caching would be suitable? But the problem will be that you will not be able to trigger the controller action so easily.
If you don't want the whole site copied, just add some specific routes or controllers (/mirrorable/...) and run the spider on them, or just access them manually (to trigger saving the content in the files).
I ended up creating one controller without a model.
rails g controller staticpages
I then created a layout file which imported the individual changes to the layout, via a "yield" tied to a "content_for" in the view files(static files(pages) in the "view of staticpages" (for example abbreviations, aboutthissite etc etc).
The rest of the static file loaded with the usual "yield" in the layout. Works a treat. No more updating the menu bar all done automatically.
To get to the correct static file I created a route using:-
match 'static/:static_page_name'=> 'staticpages#show' (or in rails 2.x:-
map.connect 'static/:static_page_name', :controller=> "staticpages", :action=> "show"
"static_page_name" variable accepted anything after "/static/" in the url and passed it to the controller "staticpages" in which I set up a show action containing:-
def show
#static_page_name = params[:static_page_name]
allowed_pages = %w(abbreviations aboutthissite etc, etc,)
if allowed_pages.include?(#static_page_name)
render #static_page_name
else
redirect_to '/' #redirects to homepage if link does not exists
end
end
I then only had to change the links in the website. (e.g.<%= link_to " About This Site ", '/static/aboutthissite' %>)
and viola! its all working.

How to implement a helper in Symfony 1.4?

I'd like to create my own helper but can't find any help on Google for Symfony 1.4/Doctrine.
I guess it has something to do with creating a myClassHelper.class.php in lib/helpers/ or something, but I don't know what to implement, or if specific methods have to be overridden.
Any help would be appreciated!
I don't think that anything changed regarding the helpers in 1.4. From the documentation(although 1.2):
Helper functions (regular PHP functions returning HTML code) should be saved in a file called FooBarHelper.php, where FooBar is the name of the helper group. Store the file in the apps/myapp/lib/helper/ directory (or in any helper/ directory created under one of the lib/ folders of your project) so it can be found automatically by the use_helper('FooBar') helper for inclusion.
So you just put normal functions in a normal file (has nothing to do with classes or methods). The functions can take arbitrary parameters (you decide what they need to create the HTML) and the have to return HTML.
E.g.
MyHelper.php
function hello_word() {
return '<strong>Hello world!</strong>';
}
and in the template:
<?php use_helper('My') ?>
<!-- somewhere in the template -->
<?php echo hello_world() ?>

Resources