In my custom template tpl file, i am showing two sections (div content) of data, one from each function of my custom module.
The data also has pagination for it, displayed below.
Initially only one block of data will be displayed. Other block of data will be hidden on the page, unless the user clicks on a tab in the page.
Now my question is, how can i show individual paginations for each of my blocks in the same page ?
If i click on a page link in block 1 and go to its page, the pagination links for another block must not be affected.
How to achieve this in Drupal 7?
// my custom module code below
// function one
func one() {
$page = strtolower($page);
$query = db_select('keyword', 'k');
$query->groupBy('k.res');
$stories = $query->extend('PagerDefault')->limit(10)->execute();
return $stories;
}
// function two
func two() {
$page = strtolower($page);
$query = db_select('videos', 'v');
$query->groupBy('v.res');
$videos= $query->extend('PagerDefault')->limit(10)->execute();
return $videos;
}
// in my custom template page
// below is first section in same page
$block_content = fun one(arg(1));
$args = array( 'parameters' => array('pg' => 'one'));
print (theme ('pager',$args));
foreach($block_content as $content)
{
// doing something to display
}
print (theme ('pager',$args));
// below is second section in same page
$block_content = fun two(arg(1));
$args = array( 'parameters' => array('pg' => 'two'));
print (theme ('pager',$args));
foreach($block_content as $content)
{
// doing something to display
}
print (theme ('pager',$args));
You can use the PagerDefault::element() method to set a unique element ID for the pager:
// First one
$stories = $query->extend('PagerDefault')->element(0)->limit(10)->execute();
// Second one
$videos = $query->extend('PagerDefault')->element(1)->limit(10)->execute();
Then use the respective element ID in the theme call:
// First one
$args = array('element' => 0, ...);
print theme('pager', $args);
// Second one
$args = array('element' => 1, ...);
print theme('pager', $args);
Related
I'm trying to develop a plugin in Moodle. One of the requirements is to add an element to the Settings Menu, in which I was able to achieve with the help of this guide
https://docs.moodle.org/dev/Local_plugins#Adding_an_element_to_the_settings_menu
And this is my code in local/myplugin/lib.php
<?php
function local_myplugin_extends_settings_navigation($settingsnav, $context) {
// question_extend_settings_navigation
global $CFG, $PAGE;
// Only add this settings item on non-site course pages.
if (!$PAGE->course or $PAGE->course->id == 1) {
return;
}
// Only let users with the appropriate capability see this settings item.
/*if (!has_capability('moodle/backup:backupcourse', context_course::instance($PAGE->course->id))) {
return;
}*/
if ($settingnode = $settingsnav->find('courseadmin', navigation_node::TYPE_COURSE)) {
$strfoo = get_string('classrecord', 'local_myplugin');
$url = new moodle_url('/course/classrecord.php', array('id' => $PAGE->course->id));
$foonode = navigation_node::create(
$strfoo,
$url,
navigation_node::NODETYPE_LEAF,
'myplugin',
'myplugin',
new pix_icon('i/grades', $strfoo)
);
if ($PAGE->url->compare($url, URL_MATCH_BASE)) {
$foonode->make_active();
}
$settingnode->add_node($foonode);
}
}
?>
I allowed the students to see the element "Class Record" in the settings menu
My concern is that how can I hide/show Class Record I added?
Any ideas would be great!
If you want only certain users to see the link, then create an appropriate capability in local/myplugin/db/access.php, e.g. 'local/myplugin:viewclassrecord', defaulting to being assigned to the 'student' role. Then check for it in the function you have defined.
e.g.
if (!has_capability('local/myplugin:viewclassrecord', $context)) {
return;
}
I created pagination and wanted to add check if user want to access page, which is not exisits. For example, there are 10 pages and user wants to open 999 page. I wanted to add error message, which will show, that there are no 999 page.
I tried this (and this worked):
public function listAction() {
$page = // getting page
$pagginator = // setting paginator
// this part will add message to the flashMessanger
if($page > $paginator->count()) {
$message = 'There are no such page';
$this->flashMessenger()->addMessage($message);
return $this->redirect()->toRoute('zfcadmin/news');
}
return new ViewModel(array(
'news' => $paginator,
));
}
This is working code. This is code for list action. This action is executed, when I type in browser this: example.com/admin/news. If I will type example.com/admin/news/page-500 browser will be redirected to example.com/admin/news and there will be message There are no such page.
I wanted to add same in other parts of my site and I got problem in index action of same controller. This is index action:
public function indexAction() {
return new ViewModel(array(
'news' => $this->getItems(),
'categoryName' => null,
));
}
As you see, I call function getItems(). Code of this function:
private function getItems($categoryId = null) {
$page = // getting page
$paginator = // getting paginator
if($page > $paginator->count()) {
$message = 'There are no such page';
$this->flashMessenger()->addMessage($message);
if($categoryId) {
return $this->redirect()->toRoute('news/category', array('category' => $categoryId));
} else {
return $this->redirect()->toRoute('news');
}
}
return $paginator;
}
I tried this and I got this error:
Fatal error: Call to undefined method
Zend\Http\PhpEnvironment\Response::count() in
F:\Server\domains\zf2-skeleton\module\News\view\news\news\index.phtml
on line 32
I realized, that it is because I returning $this->redirect as result of getItems() function and it is assigned to view variable news.
I tried this then:
if($page > $paginator->count()) {
$message = 'There are no such page';
$this->flashMessenger()->addMessage($message);
if($categoryId) {
$this->redirect()->toRoute('news/category', array('category' => $categoryId));
} else {
$this->redirect()->toRoute('news');
}
}
I am not getting any errors, but I am not getting message, that page is bad too.
I think... I bet, nobody here doesn't want to know what I think :)
Help me with this problem, please.
How to make redirect + write message to flashMessanger (so I can output it later) correctly in my case?
Update
I understand, that it is possible to return array from function get items and handle it. One of element will show should zf2 do redirect or not, another will show category id, third will containt paginator by itself, but it is dirty solution (but possible :( ).
I've got a MediaWiki site and I would like to add a tab with a very simple "read article" functionality (without any edit/comment options). I followed the manual and tried to create a namespace for it, but it still doesn't work.
The snippet from LocalSettings.php looks like this:
define("NS_ARTICLE", 500);
$wgExtraNamespaces[NS_ARTICLE] = "Article";
$wgNamespaceProtection[NS_ARTICLE] = array( '' );
$wgNamespacesWithSubpages[NS_ARTICLE] = true;
$wgContentNamespaces[] = NS_ARTICLE;
I created new methods in Title.php:
public function getReadPage() {
return Title::makeTitle( MWNamespace::getRead( NS_ARTICLE ), $this->getDBkey() );
}
In Namespace.php:
public static function getRead( $index ) {
self::isMethodValidFor( $index, __METHOD__ );
return self::isTalk( $index )
? $index
: $index + 1;
}
And in SkinTemplate.php:
$readPage = $title->getReadPage();
$content_navigation['namespaces']['article']['class'] = 'selected';
$content_navigation['namespaces']['article']['text'] = 'Article';
$content_navigation['namespaces']['article']['href'] = $readPage;
$content_navigation['namespaces']['article']['primary'] = true;
$content_navigation['namespaces']['article']['context'] = 'subject';
The Tab appeared, but it links to ":Title" instead of "Article:Title". If I look for "Article:Title" page, the following message appears:
There is currently no text in this page. You can search for this page title in other pages, search the related logs, or edit this page.
Any ideas?
Don't touch the MediaWiki sources or you'll have to redo the same thing each time you upgrade. Tab manipulation is doable with hooks, e.g. SkinTemplateNavigation.
For each member page you have a selection of components (e.g. profile, settings, activity...)
What I am trying to do is add a new component called jobs to each page. I understand how to add the link to the navigation bar. It is just creating the page that is confusing me.
Do I add a new directory, if so how do I let buddypress know.
Having a url structure like:
example.com/member/username/jobs
is important.
Thanks!
The global variable $bp is where you want to insert the new Jobs component. By dumping the global variable $bp, you can see all of the elements contained in it, including all of the components. To easily dump $bp, add the following to the top of member-header.php:
global $bp;
foreach ( (array)$bp as $key => $value ) {
echo '<pre>';
echo '<strong>' . $key . ': </strong><br />';
print_r( $value );
echo '</pre>';
}
The array within $bp that you want to add the component 'Jobs' to is bp_nav.
In functions.php add the following:
add_action( 'bp_setup_nav', 'add_subnav_items', 100 ); //Priority must be higher than 10
function add_subnav_items() {
global $bp;
//Jobs tab
$tab_array['name'] = 'Jobs';
$tab_array['link'] = $bp->displayed_user->domain.'jobs';
$tab_array['slug'] = 'jobs';
$tab_array['parent_url'] = $bp->displayed_user->domain;
$tab_array['parent_slug'] = bp_core_get_userlink(bp_loggedin_user_id());
$tab_array['css_id'] = 'jobs';
$tab_array['position'] = 100;
$tab_array['user_has_access'] = '1';
$tab_array['screen_function'] = 'bp_jobs_screen_general';
$bp->bp_nav['jobs'] = $tab_array; //Add new array element to the 'bp_nav' array
}
The 'screen_function' is a function that handles the screen that is to be shown when 'Jobs' tab is selected so you must add the function 'bp_jobs_screen_general' in functions.php:
function bp_jobs_screen_general() {
bp_core_load_template( apply_filters( 'bp_jobs_screen_general','members/single/jobs' ) );
}
This function looks for a template file named jobs.php in members/single/ so you must create it. For an example on how the screen_function's work, refer to a function for displaying Groups screens within wp-content/plugins/buddypress/bp-groups/bp-groups-screens.php.
I am using the following template library. What I am trying to do is to load one or more upper views inside a template,as an array so that I can easily load them in the template with a for-each loop.
This is a simple example on how it can be used on a controller:
function index() {
$data['title'] = 'My page title';
$partials = array('content'=>'c_location'); //Load view about inside the template.
$this->template->load('main', $partials, $data);
}
On the View you have an html like:
<html>
....
<?=$content?>
...
</html?>
This is what I am trying to use:
Controller:
$partials = array('content'=>'c_location',
array(
'first_upper_content'=>'1_u_location','second_upper_content'=>'2_u_location'
)
);
So for example I could pass for upper_content, a top header as "first_upper_content" and a slide for "second_upper_content" and then the remainder of the content for "content".
Html:
...
<?=$upper_content?>
<--if upper_content is a array,
I could display each content with a for loop-->
<?=$content?>
When I try everything I get:
Message: pathinfo() expects parameter 1 to be string, array given
Filename: core/Loader.php
Line Number: 759
How can I implement this? I am thinking of modifying the
// Load views into var array
Inside the Template.php & adding a foreach loop to the html;
This is what you want:
// Load views into var array
foreach(array_flat($view) as $key => $file)
Include the "array_flat" function call in Template.php, as shown above.
You will need to define this function. You can do this in any auto-loaded helper, or even include it the own Template class (in this case, you should call it as $this->array_flat in the code above). Here is it:
function array_flat($array)
{
$result = array();
foreach ($array as $key => $value)
{
if (is_array($value))
{
$result = array_merge($result, array_flat($value));
}
else
{
$result[$key] = $value;
}
}
return $result;
}
What you're trying to do is not possible with that library.
The error you received indicates the CI Loader class is being passed invalid data. So taking a look at the library's load function, your code will fail right here:
// Load views into var array
foreach($view as $key => $file)
{
$tpl[$key] = $this->CI->load->view($file, $vars, TRUE);
}
The library passes your nested array in $partials directly to the CI Loader. With your data, this line works out to:
$tpl[0] = $this->CI->load->view(array(
'first_upper_content'=>'1_u_location','second_upper_content'=>'2_u_location'
), vars, TRUE);
You can see in the CI user guide that isn't valid. It seems to me that your options are to either overhaul the library or change your approach.
Just make your main template view, and have something like this in it:
$this->load->view('header');
if (is_array($page) {
foreach($page as $key=>$val){
$this->load->view($key, $val); // $val being optional parameters
}
} else {
$this->load->view($page);
}
$this->load->view('footer');
In the controller, $data['page'] would contain view info, either its name (string) or an array of names to call in order. Of course, you'll have to have premade views with those names.
This was from the top of my head, but it should do what you wanted. This is done without template libraries, just plain CI.
To load partials, all you need to do is use:
$this->load->view('partial_location',$data);
inside your main view. So if you have a main view called home_page.php, and you want to load partials for headers and footers, you can just use:
$this->load->view('header');
// Main page layout
$this->load->view('footer');
If you want to use custom or different data inside your partials, just define them in your controller:
$data = array(
'content' => 'about',
'header_content' => 'Welcome to the site!',
'footer_content' => 'Made by me!'
);
And in your main view file:
$this->load->view('header',$header_content);
// would echo 'Welcome to the site!'
echo $content;
// would echo 'about'
$this->load->view('footer',$footer_content);
// would echo 'Made by me!'