I have a template in smarty like this :
Template folder
home.tpl
article.tpl
category.tpl
var.tpl
In each template file (except var.tpl), i include the file var.tpl.
home.tpl have a structure in 1 column
article.tpl have a structure in 2 columns
My template files are like this (home example) :
{include file="$tpl_dir./var.tpl"}
<div class="span{$center_column}" id="center_column">
</div>
In order to change quickly the apparence of my website, i wrote the following lines in var.tpl :
{assign var=center_column_g value=['home'=>'12','article'=>'10'] scope="root"}
{assign var=center_column_default value='10' scope="root"}
{if $center_column_g[$page_name]}
{assign var=center_column value=$center_column_g[$page_name] scope="root"}
{else}
{assign var=center_column value=$center_column_default scope="root"}
{/if}
ps : $page_name is a global variable with the name of each template page.
So with var.tpl, if i can easy change the class of my div #center_column
I have a doubt with this code :
{if $center_column_g[$page_name]}
{assign var=center_column value=$center_column_g[$page_name] scope="root"}
{else}
{assign var=center_column value=$center_column_default scope="root"}
{/if}
Is it right to assign var center_column in the root scope ?
Related
I am using the following code in my Emmet.sublime-setting to add auto comments after classes and ids. This works fine but it is now also adding forward slash on my <br> and <hr> tags when I type br[TAB] or hr[TAB] becoming <br /> and <hr />.
How can I change it to go back to the regular non trailing slash while keeping the comments.
{
"preferences": {
"filter.commentAfter": "<!-- /<%= attr('id', '#') %><%= attr('class', '.') %> -->"
},
"syntaxProfiles": {
"html" : {
"filters" : "html, c",
"html" : "html"
}
},
}
The closing slash is controlled but the output profile: http://docs.emmet.io/customization/syntax-profiles/
Another possible reason is that your document contains XHTML doctype, in this case Emmet tries to automatically match documents’ format
For search i use liferay-ui:search in the dockbar. User should be able to define search scope (specific private page) by choosing it from dropdown list.
How can i implement search on specific private page?
And 1 more question. Seems it's a bug, but user is able to search only while he is on specific private page. If he move to another page - search button is "disabled" - nothing happens when he clic it. For admin account everything works fine - i am able to search being on any page.
Thanks!
OK. 1st step was to place hook on [b]html/taglib/search/start.jsp[/b]. I passed an extra id parameter to define on which private page i gonna search.
<input name="<%= namespace %>keywords" size="30" title="<liferay-ui:message key="search" />" type="text" value="<%= HtmlUtil.escapeAttribute(keywords) %>" />
<input name="<%= namespace %>groupid" value="0" type="hidden" />
<select name="<%= namespace %>scopeId" title="<liferay-ui:message key="scope" /> ">
<option value="0" <%= selected == 0 ? "selected" : ""%>><liferay-ui:message key="everything" /></option>
<option value="1" <%= selected == 1 ? "selected" : ""%>>Новости</option>
<option value="2" <%= selected == 2 ? "selected" : ""%>>Сотрудники</option>
<option value="3" <%= selected == 3 ? "selected" : ""%>>Новому сотруднику</option>
<option value="4" <%= selected == 4 ? "selected" : ""%>>Корпоративные правила</option>
<option value="5" <%= selected == 5 ? "selected" : ""%>>Продукты</option>
<option value="6" <%= selected == 6 ? "selected" : ""%>>Wiki</option>
<option value="7" <%= selected == 7 ? "selected" : ""%>>События</option>
<option value="8" <%= selected == 8 ? "selected" : ""%>>Форум</option>
</select>
2nd step was to hook on [b]html/portlet/search/main_search.jsp[/b]. There i was going to filter [b]ALL[/b] search results and display only those which needed by request from [b]select field[/b]. It's OK for non instanceble custom portlets with have different id, i just filter by portletId and display result.
Hits hits = indexer.search(searchContext);
List<Document> documents = new ArrayList<Document>();
documents = hits.toList();
...
if (documents.size() != 0) {
List<Document> toDelete = new ArrayList<Document>();
for (Document document : documents) {
String id = document.getPortletId();
id = document.get(Field.PORTLET_ID);
switch (scopeId) {
case 0:
break;
case 1:
if (!id.equals(NEWS_PORTLET_ID)) {
toDelete.add(document);
}
break;
....
if (toDelete.size() != 0) {
documents.removeAll(toDelete);
hits.setDocs(documents.toArray(new Document[documents.size()]));
if (documents.size() == 0) {
hits.setLength(0);
}
}
All fine. But 3 of my pages all have asset publisher portlet (portletId = 15), so if i filter by portlet id - i will get results from all 3 pages. Maybe i can get instance id of portlet which document belongs to. Or maybe there is some other way to do search.
Atm i try to implement my CustomJournalArticleIndexer. The idea is Indexer adds field containing portlet's instance id. So later in main_search.jsp i can do something like document.getPortletInstanceId and compare it with a constant paired with scopeId of my request.
Any suggestions here?
Thanks and... from Russia with love!
I'm new to Orchard and have watched both the Pluralsight "Orchard Fundamentals" and "Advanced Orchard" tutorials. Its a great platform, but I'm having a hard time wrapping my head around a couple of things.
I'd like to create a blog showcase banner on the home page only that rotates blog posts on the site. I have the HTML sliced up and functioning on an HTML template. The banner looks like this:
http://arerra.com/news-slideshow.jpg
So far I have done the following:
I've created a Blog called "Articles" and have placed a single post in there for testing.
Added a Layer called "ArticleList" where I have placed a Widget for "Recent Blog Posts"
I've created a custom layout for the home page called "Layout-Url-HomePage.cshtml" in my theme.
In my Theme "Views" folder, I have created a file called "Widget.Wrapper.cshtml" with only #Display(Model.Child) in it to remove the <article><header/><footer /><article> tags globally from the widgets.
Added a file in "Views > Parts > Blogs.RecentBlogPosts.cshtml" to control the layout of my shape. The code is the following:
#using Orchard.ContentManagement;
#{
IEnumerable<object> blogPosts = Model.ContentItems.ContentItems;
}
#if (blogPosts != null) {
<div class="container news-slider">
<ul class="slide-images">
#foreach (dynamic post in blogPosts) {
string title = post.Title;
ContentItem item = post.ContentItem;
<img src="/Themes/MountainWestHoops/Content/img/placeholder-700x380.jpg" alt="#title" class="active" />
}
</ul>
#foreach (dynamic post in blogPosts) {
string title = post.Title;
string body = post.Body;
ContentItem item = post.ContentItem;
<div class="featured-story threeD active">
<h1>#title</h1>
<p>#body #Html.ItemDisplayLink("READ MORE", item)</p>
</div>
}
<aside>
<ul class="tabs">
#foreach (dynamic post in blogPosts) {
string title = post.Title;
string url = post.Url;
ContentItem item = post.ContentItem;
<li><h3>#title</h3></li>
}
</ul>
<div class="ad-three-day-trial">
<img src="/Themes/Content/img/placeholder-260x190.gif" />
</div>
</aside>
</div>
}
My HTML is rendering properly, but none of the values that I have specified are showing up.
I am using the "Shape Tracer" module to see what template is being used. What is funny, is that the #Html.ItemDisplayLink("READ MORE", item) is rendering the article's URL, and if I replace the "READ MORE" with the string title, the title renders properly.
What am I doing wrong here that is causing strings to not display? Am I missing a larger point and misunderstanding the fundamentals? The tutorials seems to say that you can simply move around parts, but in this case, I need to have very specific markup for this slider to work.
Seems like your source was http://weblogs.asp.net/bleroy/archive/2011/03/27/taking-over-list-rendering-in-orchard.aspx
That is a rather old post, and the way the title is handled has changed since then.
The DisplayLink works because the only correct property here is post.ContentItem, which is what that API takes. post.Title and post.Body on the other hand are very likely null, which is why you see nothing. To access the title, you can use post.ContentItem.TitlePart.Title and to get the body, post.ContentItem.BodyPart.Text.
I am very new to Orchard.
I have created a new theme, based on the Minty theme. The only real change is the layout, where I have adapted the html from an existing asp.net masterpage to match the orchard style razor layout.cshtml. I have experience with MVC and razor, so no problem on that side... unless I have missed something vital.
The problem is the login page. Clicking the sign in link takes me to the correct url without errors, but not login form gets rendered. I have checked that this is the case by Inspecting Element in google chrome.
I am aware that setting up widgets, etc, I can make content appear. However, I can't find how the login form gets inserted when the login url gets requested. I presume it uses the Orchard.Users module, but not sure how. Does it need a specific zone? I can't see why, but see how else.
As a result, I can't solve my problem...
Any pointers?
Any books or other learning media?
The code for my layout.cshtml is:
#functions {
// To support the layout classifaction below. Implementing as a razor function because we can, could otherwise be a Func<string[], string, string> in the code block following.
string CalcuClassify(string[] zoneNames, string classNamePrefix) {
var zoneCounter = 0;
var zoneNumsFilled = string.Join("", zoneNames.Select(zoneName => { ++zoneCounter; return Model[zoneName] != null ? zoneCounter.ToString() : "";}).ToArray());
return HasText(zoneNumsFilled) ? classNamePrefix + zoneNumsFilled : "";
}
}
#{
/* Global includes for the theme
***************************************************************/
SetMeta("X-UA-Compatible", "IE=edge,chrome=1");
Style.Include("http://fonts.googleapis.com/css?family=Handlee");
Style.Include("http://html5shiv.googlecode.com/svn/trunk/html5.js");
Style.Include("site.css");
Script.Require("jQuery").AtHead();
Script.Require("jQueryUI_Core").AtHead();
Script.Require("jQueryUI_Tabs").AtHead();
Script.Include("http://cdnjs.cloudflare.com/ajax/libs/modernizr/2.0.4/modernizr.min.js").AtHead();
Style.Include("TagDefaults.css");
Style.Include("LayoutStructure.css");
Style.Include("LayoutStyling.css");
Style.Include("TopMenu.css");
Style.Include("LeftBlock.css");
Style.Include("RightBlock.css");
Style.Include("MenuAdapter.css");
Style.Include("Content.css");
Style.Include("FloatedBoxes.css");
Style.Include("Helen.css");
/* Some useful shortcuts or settings
***************************************************************/
Func<dynamic, dynamic> Zone = x => Display(x); // Zone as an alias for Display to help make it obvious when we're displaying zones
/* Layout classification based on filled zones
***************************************************************/
//Add classes to the wrapper div to toggle aside widget zones on and off
var asideClass = CalcuClassify(new [] {"Sidebar"}, "aside-"); // for aside-1, aside-2 or aside-12 if any of the aside zones are filled
if (HasText(asideClass)) {
Model.Classes.Add(asideClass);
}
//Add classes to the wrapper div to toggle tripel widget zones on and off
var tripelClass = CalcuClassify(new [] {"TripelFirst", "TripelSecond", "TripelThird"}, "tripel-"); // for tripel-1, triple-2, etc. if any of the tripel zones are filled
if (HasText(tripelClass)) {
Model.Classes.Add(tripelClass);
}
//Add classes to the wrapper div to toggle quad widget zones on and off
var footerQuadClass = CalcuClassify(new [] {"FooterQuadFirst", "FooterQuadSecond", "FooterQuadThird", "FooterQuadFourth"}, "split-"); // for quad-1, quad-2, etc. if any of the quad zones are filled
if (HasText(footerQuadClass)) {
Model.Classes.Add(footerQuadClass);
}
var slideshowClass = CalcuClassify(new[] {"HomeSlideshow"}, "slideshow-");
if (HasText(slideshowClass)) {
Model.Classes.Add(slideshowClass);
}
/* Inserting some ad hoc shapes
***************************************************************/
//WorkContext.Layout.Header.Add(New.Branding(), "5"); // Site name and link to the home page
//WorkContext.Layout.Footer.Add(New.BadgeOfHonor(), "5"); // Powered by Orchard
WorkContext.Layout.Footer.Add(New.User(), "10"); // Login and dashboard links
/* Last bit of code to prep the layout wrapper
***************************************************************/
Model.Id = "layout-wrapper";
var tag = Tag(Model, "div"); // using Tag so the layout div gets the classes, id and other attributes added to the Model
}
#tag.StartElement
<a name="top"></a>
<div id="SiteHeader">
</div>
<div id="PageContainer">
<div style="position: absolute; Left:-80px; top:-88px;z-index:1000;">
<img id="bird" title="Pheasant" src="/Themes/TheFarmsBlogs/Styles/Images/PositionedImages/pheasant.gif" />
</div>
<div class="SiteMenu"><p>Hello Menu</p></div>
<div id="Specialized">
<div id="PageName">
<!--
PageName NOT in use!
-->
</div>
#if (Model.RightColumn != null) {
<div id="RightCol">
#Zone(Model.RightColumn)
</div>
}
<!-- Page divided into two main columns, of which the left column is subdivided as necessary -->
<div id="LeftCol">
<div id="PageBanner">
<div id="PageBannerLeft">
#if (Model.MainImage != null) {
<div id="PageBannerImage">
#Zone(Model.MainImage)
</div>
}
#if(Model.TheStrip != null) {
<div id="TheStrip">
#Zone(Model.TheStrip)
</div>
}
</div>
</div>
<div id="SpecializedContent">
#if(#Model.content != null)
{
#Zone(Model.content)
}
</div>
</div>
<div id="SpecializedFooter">
</div>
</div>
<div id="PageFooter">
#if (Model.FooterPage != null){
#Zone(Model.FooterPage)
}
</div>
</div>
<div id="SiteFooter">
#Display(Model.Footer)
The Farms Ltd - © 2007
</div>
#tag.EndElement
PS: the branding and badge of honour are commented out as I am only enabling bit by bit to eliminate the source of errors. It will be in the live site.
ADDENDUM:
See Bertrand Le Roy's answer below. The Orchard.Users module requires a Content zone with a Capital C. That instantly cured the problem.
I added this as Bertrand's response was tentative, and I wanted to reinforce that the problem was the name of the zone.
In Orchard.Users, look for Controllers/AccountController.cs. In there, there is a LogOn action. It creates a LogOn shape that it then puts in a shape result. This then gets resolved as the Views/LogOn.cshtml template (which you can override in your theme by just dropping a file with the same name in there, for example a copy of the original that you can tweak). The LogOn template will be rendered within the theme's layout, in the Content zone. Does this answer your question?
I think the mistake you made was to name your Content zone content (notice the casing).
Pagination link not working on expression engine exp:search results.Page does not display the new result when pagination link is clicked.
{exp:search:total_results}</b>Result(s) for <b>{exp:search:keywords}
{exp:search:search_results entry_id={entry_id}
switch="#000000|#003300" status="Open"
dynamic="off" orderby="date" sort="desc"}
{exp:search:search_results switch="resultRowOne|resultRowTwo" paginate="bottom" limit="2"}
<?php $articlePath = "article";?>
{related_entries id="article_feature"}
{if title == "Bay Blog"}<?php $articlePath = "blog";?>
{/related_entries}
<b>{title}</b> from <em>{related_entries id="article_feature"}{title} {/related_entries}</em><br/>
{if:else}
<b>{title}</b> from <em>{related_entries id="article_feature"}{title} {/related_entries}</em><br/>
{/if}
{exp:trunchtml chars="250" inline="..."}
{article_body}
{/exp:trunchtml}
{related_entries id="article_issue"}
[ {title}] {/related_entries}
<br><br>
{if no_results}
Sorry!, Search result found!
{/if}
{/exp:search:search_results}
{paginate}
<div class='paginate'>
<span class='pagecount'>{page_count}</span>
</div>
{paginate}
When returning search results, use the auto_path variable when building your URLs:
{title}
Unlike other path variables, this variable does not require the Template Group and Template Name to be specified.
Instead, the path will automatically be determined by the Search Results URL setting for the channel in Channel Management.
Admin > Channel Administration > Channels > Preferences:
If you're using ExpressionEngine's Pages Module or Structure to create static pages, the following use case may be of help to you as well:
{if page_url == ""}
// If the Search Result is a Dynamic Page
{title}
{/if}
{if page_url != ""}
// If the Search Result is a Static Page
{title}
{/if}
You can also test to see what channel the search result is being fetched from and act on it conditionally:
{if channel_name == "about"}
{title}
{if:else}
{title}
{/if}