is_singular() for custom post type in pre_get_posts - custom-post-type

I'm trying to modify the query for a specific post type, whatever page (single or archive) is currently displayed. I'm using the pre_get_posts filter with this test:
if ( is_singular( 'evenement' ) || is_post_type_archive( 'evenement' ) ) {
// do something
}
but the is_singular conditional tag never seems to be true when I'm on a single evenement page.
Any idea what I could have missed?
Thanks for helping.

I had the same issue and figured that you can't use is_singular in pre_get_posts because the queried object is not set at this point. It make sense: the query isn't processed yet, and is_singular return true if a post is being displayed - we don't know at this point if the query return any result, as of pre​_get_posts).
You can use instead the post_type query parameter like this:
if($query->get('post_type') === 'evenement') {
// ... do stuff
}

You can use '$query->is_singular' in combination with a post_type check:
if ( $query->is_singular && $query->get('post_type') === 'your_post_type' ) {
// your code
}
If you only test for post type then you will also modify the query for archive pages.

Related

Switch vs if else

I use if else for custom menus in Wordpress, to load various location menus based on parent page. The agency I work for is adding countless amounts of cities, and it's getting out of hand. One thing I am trying to do, is come up with a more efficient way to check the items, someone suggested switch, and I just wanted to throw this out there and see what you all think. These are not complete codes, and I know the menus are bad UX, and all that, it's not my call. I just want some input on performance differences. thanks.
Here is an example of switch code:
function is_subpage() {
global $post; // load details about this page
if ( is_page() && $post->post_parent ) { // test to see if the page has a parent
return $post->post_parent; // return the ID of the parent post
} else { // there is no parent so ...
return false; // ... the answer to the question is false
}
}
$selectedMenu = "primary";
$my_page_id = is_subpage();
if(!$my_page_id)
$my_page_id = get_the_ID();
switch ($my_page_id) {
case('489'):
$selectedMenu = 'columbus';
break;
case('6583'):
$selectedMenu = 'cumming';
break;
}
wp_nav_menu( array(
'theme_location' => 'main-menu',
'menu' => $selectedMenu,
'menu_class' => 'clearfix'
));
and here is an example of if else code:
if(is_page( '28' ) || '28' == $post->post_parent) { $locationMenu = 'louisville'; }
'menu' => $locationMenu,
Don't second guess or assume anything about the efficiency of an interpreter or compiler. if else might be better at one scenario and switch at another.
The problem with your code is readability and maintainability and not performance. It is hard to be specific without knowing all details about your needs, but it seems like what you need is to have at each post a custom field which indicates the menu associated with that post, and then the admin can configure them and you will have some more coffee time ;)
This is actually a worse solution in terms of performance, but if you really need the site to be fast then you are going to use a caching plugin which will make the whole php related performance discussion just a waste of time.
From a PHP perspective...
In lieu of having the page id to location table in a database, you could include a structure like this on pages you need it:
$idToLocation = array(
"489" => "columbus",
"6583" => "cumming"
// et cetera
);
Then to get the location:
$id = "489"; // for example
if (!array_key_exists($id, $idToLocation)) {
echo "location for id not found";
die();
}
$location = $idToLocation[$id];

Laravel Slugs with Str::slug

Looking at Str::slug for my frontend URL generation but just wondering how you guys go about implementing it with routes etc, for example, how would you guys go about changing http://www.example.com/courses/1 to http://www.example.com/courses/this-course
OK, I did it this way:
// I have a slug field in my courses table and a slug field in my categories table, along with a category_id field in my courses table.
// Route
Route::get('courses/{categorySlug}/{slug?}', function($categorySlug, $slug) {
$course = Course::leftJoin('categories', 'categories.id', 'courses.category_id')
->where('categories.slug', $categorySlug)
->where('courses.slug', $slug)
->firstOrFail();
return View::make('courses.show')->with('course', $course);
});
Works like a charm. It gets the $categorySlug and $slug variables then uses them to filter the Eloquent model Course to get the correct course object from the database.
EDIT: You can generate a URL in your view like:
http://www.example.com/courses/it-training/mcse
By doing something like:
{{ $course->title }}
A have a method in my Category like below that retrieves the parent category slug. This could be better achieved though using some sort of presenter class which would allow you to simply use $course->url but I haven't got around to doing this yet. I will update the answer when I do.
public function parentCategorySlug($parentId)
{
if ($parentId === '0')
{
return $this->slug;
}
return $this->where('id', $parentId)->first()->slug;
}
You can use the cvierbrock's Eloquent-Sluggable package.
As for me I created a helper function and used the following method taken from here.
public static function getSlug($title, $model) {
$slug = Str::slug($title);
$slugCount = count( $model->whereRaw("url REGEXP '^{$slug}(-[0-9]*)?$'")->get() );
return ($slugCount > 0) ? "{$slug}-{$slugCount}" : $slug;
}
You can create a related model Slug, and approach the course in your methods like so:
$course = Slug::where('slug', $slug) -> firstOrFail() -> course;
I have also implemented a similar URL mapping but I preferred to have both the ID and the slug in the requested URL, like this:
http://www.example.com/courses/1/my-laravel-course
This method allows me to get the requested course object from the ID given in the URL, rather than having to store the slugs in my DB table.
Route::post('courses/(:num)/(:any)', function ($courseid, $slug) {
$course = Course::where('id', '=', $courseid)->get();
return View::make('courses.show')->with('course', $course);
}
For Laravel 8:
Given my URL:
http://www.example.com/courses/this-course
My route:
Route::get('/courses/{course:slug}' , function(Course $course){
return view('showCourse' , [
'course' => $course
])
})

The right pattern for returning pagination data with the ember-data RESTAdapter?

I'm displaying a list of articles in a page that are fetched using the Ember Data RESTAdapter. I need to implement a bootstrap'esque paginator (see: http://twitter.github.com/bootstrap/components.html#pagination) and cant seem to find a sane pattern for returning pagination data such as, page count, article count, current page, within a single request.
For example, I'd like the API to return something like:
{
articles: [{...}, {...}],
page: 3,
article_count: 4525,
per_page: 20
}
One idea was to add an App.Paginator DS.Model so the response could look like:
{
articles: [{...}, {...}],
paginator: {
page: 3,
article_count: 4525,
per_page: 20
}
}
But this seems like overkill to hack together for something so trivial. Has anyone solved this problem or found a particular pattern they like? Is there a simple way to manage the RESTAdapter mappings to account for scenarios such as this?
Try to use Ember Pagination Support Mixin and provide your own implementation of the following method. Instead of loading all the content, you can fetch the required content when the user is navigating the pages. All what you need initially is the total account of your records.
didRequestRange: function(rangeStart, rangeStop) {
var content = this.get('fullContent').slice(rangeStart, rangeStop);
this.replace(0, this.get('length'), content);
}
With ember-data-beta3 you can pass a meta-property in your result. The default RESTSerializer looks for that property and stores it.
You can access the meta-data like this:
var meta = this.get("store").metadataFor("post");
If you are not able to change the JSON returned from the server you could override the extractMeta-hook on the ApplicationSerializer (or any other Model-specific serializer).
App.ApplicationSerializer = DS.RESTSerializer.extend({
extractMeta: function(store, type, payload) {
if (payload && payload.total) {
store.metaForType(type, { total: payload.total }); // sets the metadata for "post"
delete payload.total; // keeps ember data from trying to parse "total" as a record
}
}
});
Read more about meta-data here

How do you deal with the fact, that URLs are case sensitive in xPages?

How do you deal with the fact, that URLs are case sensitive in xPages even for parameters? For example URL:
my_page.xsp?folderid=785478 ... is not the same as ...
my_page.xsp?FOLDERID=785478
How to make, for example, a proper check that params contain some key e.g.
param.containsKey("folderid") which desnt work when there is 'FOLDERID' in URL.
I'd suggest defining a couple convenience #Functions:
var #HasParam = function(parameter) {
var result:boolean = false;
for (var eachParam : param.keySet()) {
if (eachParam.toLowerCase() == parameter.toLowerCase()) {
result = true;
break;
}
}
return result;
};
var #GetParam = function(parameter) {
var result = "";
if (#HasParam(parameter)) {
for (var eachParam : param.keySet()) {
if (eachParam.toLowerCase() == parameter.toLowerCase()) {
result = param.get(eachParam);
break;
}
}
}
return result;
};
Then you can safely query the parameters without caring about case. For bonus points, you could add requestScope caching so that you can skip looping through the keySet if you're examining a parameter that you've previously looked at during the same request.
you may use this function:
context.getUrlParameter('param_name')
then test if it's null or not.
make sure to decide for one,so either upper or lowercase
other than that i'd suggest something like
KeyValuePair<string,string> kvp = null;
foreach(KeyValuePair<string,string> p in param)
{
if(UPPERCASE(p.Key) == UPPERCASE("folderid"))
{
kvp = p;
break;
}
}
syntax isn't correct and idk the uppercase method in c# right now,but you get the point
The easiest answer is ofcourse the obvious. Be sure that the parameters you are using througout your application are always the same on every url you are generating and know what to expect. A good approach to accomplish this is to create a ssjs function which generates url's for you according to the objects you submit.
In this function you could check which object you are receiving and with the use of keywords and so forth generate the correct url. This way generating twice a url with the same input parameters should always generate the exact same url.
another option would be just to double check with a bit of code like this
var key = "yourkey";
if(param.contains(#uppercase(key)) || param.contains(#lowercase(key)){
// do stuff
}
But should not be necesarry if the url you are parsing is generated by your own application
Edit after post of topic starter
Another option would be to grap the url directly from from the facescontext and to convert it to a string first. When it is a string you can parse the parameters yourself.
You can combine server side substitution/redirection to get around the issue that David mentioned. So a substitution rule will redirect incoming patern like this:
http://myhost/mypage/param (/mypage/* => which converts to - /dbpath/mypage.xsp?*) - substitution is tricky so please handle with care.
Also I believe I read somewhere that context.getUrlParameter is not case sensitive - can someone please confirm this.
Hope this helps.

Module created page - cached?

This should be a very simple question, but I'm finding it surprisingly hard to find an answer.
I'm creating custom pages using hook_menu that have both static content and dynamic aspects, (mainly from sql queries and views embeds etc...). My question is, how does drupal's cache system treat these custom pages?
I'm concerned because as the traffic ramps up on some occasions, I feel like I need some kind of caching control over the display of these pages, but at this point, I have no idea if they're automatically being cached, or if I need to somehow specify to drupal that I do indeed want them cached.
Just to clarify, these pages are not admin pages, but are accessible by anyone.
The result of a menu callback is cached only when the menu callback returns the output; when the menu callback prints the output, it's not cached.
The code execute to bootstrap Drupal when a page is requested is the following:
require_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
$return = menu_execute_active_handler();
// Menu status constants are integers; page content is a string.
if (is_int($return)) {
switch ($return) {
case MENU_NOT_FOUND:
drupal_not_found();
break;
case MENU_ACCESS_DENIED:
drupal_access_denied();
break;
case MENU_SITE_OFFLINE:
drupal_site_offline();
break;
}
}
elseif (isset($return)) {
// Print any value (including an empty string) except NULL or undefined:
print theme('page', $return);
}
drupal_page_footer();
drupal_page_footer() is the function that caches the result.
function drupal_page_footer() {
if (variable_get('cache', CACHE_DISABLED) != CACHE_DISABLED) {
page_set_cache();
}
module_invoke_all('exit');
}
page_set_cache() is the function that does the real work.
function page_set_cache() {
global $user, $base_root;
if (!$user->uid && $_SERVER['REQUEST_METHOD'] == 'GET' && page_get_cache(TRUE)) {
// This will fail in some cases, see page_get_cache() for the explanation.
if ($data = ob_get_contents()) {
if (variable_get('page_compression', TRUE) && extension_loaded('zlib')) {
$data = gzencode($data, 9, FORCE_GZIP);
}
ob_end_flush();
cache_set($base_root . request_uri(), $data, 'cache_page', CACHE_TEMPORARY, drupal_get_headers());
}
}
}
The content is compressed (if the zlib is enabled), and saved in the cache.
If you want the cache the output of a custom menu callback, then you just need to return the output, instead of printing it directly.
function mymodule_callback() {
// …
return $output;
}
Instead of caching the output of the page, you can cache the data the module used to build its output. If, in example, the output data is obtained with an SQL query, you can cache the result of the query.

Resources