Expression Engine- Show HTML within entries loop even if no results - expressionengine

New to Expression Engine. I have the following code:
{exp:channel:entries channel="blogposts" orderby="date" url_title="{segment_3}" limit="1"}
<div id="cat_head_section">
<div id="cat_title">
<div id="lower_bubble_heading" class="cat_title"><h5>{title}</h5></div>
</div>
</div>
<div id="category_main">
{if no_results}
<h2>Sorry, the post you were looking for either does not exist or has been deleted.</h2>
{/if}
{url_title}
</div>
{/exp:channel:entries}
When there are no results returned, I don't get any of the HTML returned (other than the heading), which is vital to the structure of the page. How do I solve this?
Thanks.

This answer assumes that the entry call you are making here is the main one on the page. If this call is really just for a sidebar or something then this answer may not apply.
Couple of things...
If you are building urls like EE "expects" you to you shouldn't have to specify which url segment to look for the url title. The 'url_title' parameter is generally useful when you are doing something that EE does not expect, such loading a specific entry other than the one that appears in the last segment.
If you are limiting your result to one entry, there's no need to specify an order.
Maybe the reason you think you need the 'url_title=' parameter is because you haven't taken a good look at 'require_entry='.
So we are down to this:
{exp:channel:entries channel="blogposts" limit="1" require_entry="yes"}
Now on to your question:
Think about why and how someone would end up asking for a page that you can't find.
Did the entry get deleted? Did someone retweet a mal-formed URL?
A. You may say these requests really call out for 404 response.
Serving a true 404 instead of a valid page with a "Sorry..." message ensures that the bad page will not be indexed by search engines...
To handle this you want EE's redirect tag.
{if no_results}
{redirect="404"}
{/if}
You'll want to have a genuinely helpful 404 page if you do this.
B. Alternatively you may say that when an entry can't be found you already have in mind a 'next best place' to sent the visitor -- better than your site's 404 page.
So if your visitor is looking for a blog entry that doesn't exist (say: /blog/entry/bad_page) the best place to send them would be to your blog index page (say: /blog). If you care about search ranking, then to the extent that the inbound link that is breaking had some SEO value, a 301 redirect here will help to confer that SEO value on to the page to which you are redirecting.
{if no_results}
{redirect='blog/' status_code="301"}
{/if}

The only thing that will show up if there are no results is what's in between the {if no_results} "if" statement. If you want more HTML in there, you just have to add it in there (which looks like you are duplicating it but you won't be because only one or the other will show up - results or no results).

Alternately, if you'd rather not duplicate the code you might choose to save yout HTML as a separate embedded template, and then pass the appropriate values to it as variable parameters. If no results, assign apologies to your variable values.
See http://ellislab.com/expressionengine/user-guide/templates/embedding.html

Related

Kentico 9 search result transformation

We've noticed a bug when looking at French search results. in the CMS Desk, i've kept the Page Name in English for the French content. The issue is, these are showing on the French results page.
in the transformation, based off the default one, I present the clickable title like this:
<a href='<%# SearchResultUrl() %>' data-type="title" target="_blank" ><%#SearchHighlight(HTMLHelper.HTMLEncode(CMS.ExtendedControls.ControlsHelper.RemoveDynamicControls(DataHelper.GetNotEmpty(Eval("Title"), ""))), "<span class='highLight'>", "</span>")%></a>
Here's my thinking, if the Menu Caption is filled out, use that rather than title. How do i output DocumentMenuCaption without adjust the search fields on the menu page type?
I think my logic is, check if DocumentMenuCaption is emtpy, if it use, use Title.
You should be able to continue using GetNotEmpty and just pass in the DocumentMenuCaption first, something like this:
<%# GetNotEmpty(GetSearchValue("DocumentMenuCaption");Eval("Title")) %>
You may or may not need the "GetSearchValue" function, but that allows you to grab values from the object that may not be available in the default set of columns for the search results.
Alternatively, you should be able to use the IfEmpty() method:
<%# IfEmpty(GetSearchValue("DocumentMenuCaption"), Eval("Title"), GetSearchValue("DocumentMenuCaption")) %>
Both transformation methods taken from here (double check syntax on "GetNotEmpty" as there are different ways it's implemented: https://docs.kentico.com/k9/developing-websites/loading-and-displaying-data-on-websites/writing-transformations/reference-transformation-methods
You can read more about the search transformations here: https://docs.kentico.com/k9/configuring-kentico/setting-up-search-on-your-website/displaying-search-results-using-transformations

How to include the query string in Expression Engine pagination links?

I am working on an Expression Engine site and am trying to fix a bug with pagination. A user performs a search which displays paginated results. The search terms are in a query string, so all I need to do is include the query string in the pagination links. However, I don't know how to configure this in Expression Engine. This is all I have to work with:
{paginate}
<div class="results-pager">
Page {current_page} of {total_pages} pages {pagination_links}
</div>
{/paginate}
Can I pass some sort of option to {pagination_links} to include the query string in the links it generates? Or do I need to write this code myself?
I found a way to do it. If you enable PHP code in your templates, you can manually recreate the pagination_links functionality and include the query string in the generated links.
Replace this:
{pagination_links}
With this:
{if total_pages > 1}
<div class="pagination">
{pagination_links}
{first_page}‹ First{/first_page}
{previous_page}‹ Prev{/previous_page}
{page}
{if current_page}
<strong>{pagination_page_number}</strong>
{if:else}
{pagination_page_number}
{/if}
{/page}
{next_page}Next ›{/next_page}
{last_page}Last ›{/last_page}
{/pagination_links}
</div>
{/if}
You might take a look at this free add-on:
http://devot-ee.com/add-ons/better-pagination
Not sure it's the exact fit for what you're doing though, it might allow you to do what you want without turning PHP on.

Redirect when last segment missing

I have a single entry url structure like:
www.site.com/template_group/template_1/entry_id
But I want it to be:
www.site.com/template_group/template_1/entry_id/url_title.
Entry_id would be the segment feeding exp:channel:entries. How can I redirect www.site.com/template_group/template_1/entry_id to www.site.com/template_group/template_1/entry_id/url_title.
Thanks a lot!
Something like the following should work - it's untested, but it'll give you a good idea of how to go forward with it.
{if segment_4==""}
{exp:channel:entries channel="x" limit="1" dynamic="no" entry_id="{segment_3}"}
{redirect="template_group/template_1/{entry_id}/{url_title}"}
{/exp:channel:entries}
{/if}
put this at the very top of your template:
{if segment_4 == ""}
{exp:channel:entries channel="channel_goes_here" entry_id="{segment_3}"}
{redirect="{site_url}/{segment_1}/{segment_2}/{segment_3}/{url_title}
{/exp:channel:entries}
{/if}
This will check if you have set a fourth segment, if not it takes the third segment containing your entry_id, feeds it to the channel entries tag, which returns the url_title you need. With this url_title you can easily redirect to the correct page.
Good answers from janvl and madebyhippo
Quick note if you are using complex conditionals (the ones in the answers are simple ones so you will not have that problem) is that EE will parse the channel entries tags they contain, wich can slow down performance.
If you find yourself in that situation, best to avoid the problem altogether using Mark "The croxton" addons like switchee or ifelse

How can I hide certain text from search engines?

In my WordPress blog, I have "Posted ? days ago" on every post. I have 10 posts on my homepage. So according to most keyword analysis tools, "days ago" is a top keyword on my blog, but I don't want it to be. How can I hide those words from search engines?
I don't want to use Javascript. I can easily use PHP and the $_SERVER variable, but I'm afraid I might get penalized for cloaking. Is there a HTML tag or an attribute like rel="nofollow" that I can use?
From Is there any way to have search engines not index a certain section of a page?
Supposedly you can add the class
robots-nocontent to elements on your
page, like this:
<div class="robots-nocontent">
<p>Ignore this stuff.</p>
</div>
Yahoo respects this, though I
don't know if other search engines
respect this. It appears Google is
not supporting this at this time.
I suspect if you load your content via
ajax you would get the same effect of
it not being present on the page.
and
There's no general way to do that and
personally I wouldn't bother with it.
Search engines are pretty good at
recognizing relevant content on a
page, and even though that content
might show up in the keywords that
search engines have found, it doesn't
mean that it would make the page
relevant for those keywords.
If you have a page about "Fish" and a
page about "Dogs" (that has the link
to the page about "Fish" somewhere in
the sidebar), search engines will
generally be able to recognize that
the page about "Fish" is much more
relevant for "Fish" than the page
about "Dogs" that mentions "Fish" in
the sidebar. It's possible that both
pages might be found at some point,
but generally given that mostly one
page from the site is shown in the
search results, that's not something
worth worrying about.
There's no need to be fancy with that,
and search engines are likely to just
get more confused if you try (eg if
you use JavaScript to hide the
content, you never know when search
engines will start to find that
content regardless). Similarly, using
iframes with robots.txt disallows or
AJAX will frequently degrade the
quality of your pages to users (slow
it down or make it less usable on a
variety of devices), so unless there
is a very, very strong & proven reason
that you need to do this, I would
strongly recommend not bothering with
it.
What I have found on wiki:
For Yandex:
<!--noindex-->Don't index this text.<!--/noindex-->
For Yahoo:
<div class="robots-nocontent">Don't index this text.</div>
For Google:
<!--googleoff: index--> Don't index this text.<!--googleon: index-->
Linksku, I'm fairly sure you shouldn't be worried about that particular piece of text. Our algorithms do a relatively good job detecting boilerplate text. As far as I can tell from your question, this text is boilerplate and we likely already know that.
As for detecting Googlebot and don't serving this text for it, you're right, that would be cloaking and you should never do it. In this case if you hide that text from us, we will also have a hard time detecting it's boilerplate and you would end up doing exactly what you're trying to avoid :)
I worked this out and posted it up at: http://www.scivillage.com/thread-2580.html
This should work, however more testing of it and feedback would be appreciated.
.x:before{
content:attr(title);
display:inline;
}
<ul>
<li><span class="x" title="Homepage"></span></li>
<li><span class="x" title="Contact" /></li>
</ul>
(I kept the class name short to reduce mark-up creep)
The search engines should ignore HTML tags with empty values when comes to looking for keywords, this should mean that it ignores what is written in the title attribute. (It assumes that the value is what's important, if it's empty then there is no point checking the attributes)
It was suggested that it's possible to negate having the closing tag in HTML5 due reduced strictness, however there is counter suggestions that end tags are still required.
I'd suggest not using it directly on a (anchor) tags since they can be used for sitemaps (using #), so it's means they would like have the Title spidered.
Although it is possible that it might assume any title content is there to inflate keywords through hidden elements, however I can not confirm this.
To exclude specific text from Google search results you can add data-nosnippet attribute.
https://developers.google.com/search/reference/robots_meta_tag#data-nosnippet-attr
From google documentation
You can also prevent certain parts of the page text content from being shown in a snippet by using data-nosnippet.
HTML:
<div class="hasHiddenText">_</div>
It is important that you leave a non-whitespace character between the element with a hidden text.
External CSS:
.hasHiddenText{
content: "Your hidden text here...";
/*This ovewrites the default content of the div but it isn't supported by all browsers.*/
}
.hasHiddenText::before{
content: " Your hidden text here...";
/*Places a hidden text above the div.*/
}
The "hidden text" pertains to content hidden to all search engines but visible to visitors.
You can also use nextline and all sorts of Unicode characters by escaping them with \uXXXX. To display linebreak characters correctly, be sure to add the
white-space:pre-line;
property.

Pagination on Single-Entry view in ExpressionEngine

I am building a website with ExpressionEngine as the CMS. There is a "Work" section that displays all the projects, and a detail view that shows each project individually. It is at this point, on the single-entry view that I would like to have "prev" and "next" pagination. In my tests I have made it work when the URL is "somedomain.com/index.php/work/detail/" but it does not work when the specific entry is part of the URL: "somedomain.com/index.php/work/detail/some_project/"
I've tried putting the pagination code outside of the {exp:weblog:entries} tag as well as within it, but to no avail. This is what my pagination code looks like:
{paginate}
<ul>
{if previous_page}
<li>< previous</li>
{/if}
{if next_page}
<li>next ></li>
{/if}
</ul>
{/paginate}
You are using pagination for lists of entries, what you need is the next / previous entry tags:
http://expressionengine.com/user_guide/modules/channel/entry_linking.html
Hmm. I'm not sure what the issue is here, as I've never used the {pagination} tag in that way. After checking out the docs, I see that the example code for prev/next links inside of the {pagination} tag is wrapped inside of an {exp:comment:entries} loop instead of the normal {exp:channel:entries} loop.
The docs aren't very clear about the scope of this particular feature of the {pagination} tag. You might want to double check that, in your {exp:channel:entries} loop, you haven't included pagination as a value in the disable parameter.
You could also check out the page in EE's user guide about Next/Prev Linking, which details the use of {exp:channel:next_entry} and {exp:channel:prev_entry} tags in place of the {pagination} tag that you've been using. I've used these tags without a hitch, so I definitely recommend trying them if you can't get your method to work.
Best of luck!

Resources