I have defined:
A structure
Two or mote templates associated to the structure (full content, short block abstract, ...)
A web content in the given structure
in a different template I have the functions to gather the reference to my article; I wish to render an article with a given template.
...
#set( $templateId = 27121)
#set ($DDMTemplateLocalService = $serviceLocator.findService("com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalService"))
#set( $ddmTemplate = $DDMTemplateLocalService.getTemplate($templateId))
#if( ( $articleId != $reserved-article-id.data ) )
#set( $webContent = $journalContentUtil.getContent( $groupId, $articleId, $ddmTemplate.getPrimaryKey(), "view", "$locale", $xmlRequest ) )
#if ( $webContent )
<div>${webContent}</div>
#else
<div>Cannot use $templateName</div>
#end
#end
... the variable $webContent is always empty .
The reply comes from liferay forum https://www.liferay.com/community/forums/-/message_boards/view_message/45238697
"Method getContent of JournalContentUtil gets ddmTemplateKey as a third parameter, not ddmTemplateId. These are two different properties of DDMTemplate. If you use $ddmTemplate.getTemplateKey() instead of $ddmTemplate.getPrimaryKey(), it should work (of course if there are no other bugs)."
thanks to Krzysztof Gołębiowski
When you are outside of a Velocity tag, you need to use ${webContent}. The same goes for Freemarker.
Related
Below is a working code of a ToolbarButton in Genie. The objective is to get the uri for the chosen file and return it back to the construct/init of the class. The problem is that in all examples I’ve come across global _variables are used (as shown in the code below). It looks unintuitive and I fear that whenever the code gets larger, it will become more difficult to remove bugs, since these variables will start to accumulate. Is any other way of making the function openfile return the uri to a regular variable within the construct/init of the class?
Here is the code:
uses
Granite.Widgets
Gtk
init
Gtk.init (ref args)
var app = new Application ()
app.show_all ()
Gtk.main ()
// This class holds all the elements from the GUI
class Application : Gtk.Window
_view:Gtk.TextView
_uri:string
construct ()
// Prepare Gtk.Window:
this.window_position = Gtk.WindowPosition.CENTER
this.destroy.connect (Gtk.main_quit)
this.set_default_size (400, 400)
// Headerbar definition
headerbar:Gtk.HeaderBar = new Gtk.HeaderBar()
headerbar.show_close_button = true
headerbar.set_title("My text editor")
// Headerbar buttons
open_button:Gtk.ToolButton = new ToolButton.from_stock(Stock.OPEN)
open_button.clicked.connect (openfile)
// Add everything to the toolbar
headerbar.pack_start (open_button)
show_all ()
this.set_titlebar(headerbar)
// Box:
box:Gtk.Box = new Gtk.Box (Gtk.Orientation.VERTICAL, 1)
this.add (box)
// A ScrolledWindow:
scrolled:Gtk.ScrolledWindow = new Gtk.ScrolledWindow (null, null)
box.pack_start (scrolled, true, true, 0)
// The TextView:
_view = new Gtk.TextView ()
_view.set_wrap_mode (Gtk.WrapMode.WORD)
_view.buffer.text = "Lorem Ipsum"
scrolled.add (_view)
def openfile (self:ToolButton)
var dialog = new FileChooserDialog ("Open file",
this,
FileChooserAction.OPEN,
Stock.OK, ResponseType.ACCEPT,
Stock.CANCEL, ResponseType.CANCEL)
//filter.add_pixbuf_formats ()
//dialog.add_filter (filter)
case dialog.run()
when ResponseType.ACCEPT
var filename = dialog.get_filename()
//image.set_from_file(filename)
if (dialog.run () == Gtk.ResponseType.ACCEPT)
_uri = dialog.get_uri ()
stdout.printf ("Selection:\n %s", _uri)
dialog.destroy ()
Or shouldn't I worry at all about _variables accumulating?
First a note on terminology and then a generalisation.
A "global variable" can be accessed any where in your program, so its scope is global. The _variables you are referring to in your question are private fields within the scope of your object. They can only be accessed by code that is defined in that object. You are, however, right to be concerned about the accumulation of private working variables within your objects.
Designing objects is hard to do and techniques and ideas have evolved over several decades of practise and research. The SOLID acronym, introduced by Michael Feathers, sums up five principles for object oriented design that provide useful criteria for evaluating your design. Also the book, Design Patterns: Elements of Reusable Object-Oriented Software, by Gamma et al. and first published in 1994, provides a good summary and categorisation of designs in object oriented programming. That book uses a document editor as a case study for demonstrating the use of such patterns. Both the SOLID principles and the design patterns in the book are abstractions, they won't tell you how to write a program but they do give a set of common ideas that allows programmers to discuss and evaluate. So I will use both of those tools in my answer, but be aware in recent years additional techniques have been developed to further enhance the software development process, specifically test driven development and behaviour driven development.
The S in SOLID stands for the Single Responsibility Principle and is a good starting point for looking at your example. By calling your object, Application, and thinking of the private working variables as global variables then it suggests you are writing the whole application within a single object. What you can do is start to separate Application in to a number of different objects that focus more on a single area of responsibility. First though I thought I would rename the Application object. I went for EditorWindow. In my example below EditorWindow also has a Header and a DocumentView.
Compile the code below with:
valac -X -DGETTEXT_PACKAGE --pkg gtk+-3.0 text_editor_example.gs
The use of -X -DGETTEXT_PACKAGE is explained at the end of this answer.
[indent=4]
uses
Gtk
init
Intl.setlocale()
Gtk.init( ref args )
var document = new Text( "Lorem Ipsum" )
var header = new Header( "My text editor" )
var body = new DocumentView( document )
var editor = new EditorWindow( header, body )
var document_selector = new DocumentFileSelector( editor )
var load_new_content_command = new Load( document, document_selector )
header.add_item( new OpenButton( load_new_content_command ) )
editor.show_all()
Gtk.main()
class EditorWindow:Window
construct( header:Header, body:DocumentView )
this.window_position = WindowPosition.CENTER
this.set_default_size( 400, 400 )
this.destroy.connect( Gtk.main_quit )
this.set_titlebar( header )
var box = new Box( Gtk.Orientation.VERTICAL, 1 )
box.pack_start( body, true, true, 0 )
this.add( box )
class Header:HeaderBar
construct( title:string = "" )
this.show_close_button = true
this.set_title( title )
def add_item( item:Widget )
this.pack_start( item )
class OpenButton:ToolButton
construct( command:Command )
this.icon_widget = new Image.from_icon_name(
"document-open",
IconSize.SMALL_TOOLBAR
)
this.clicked.connect( command.execute )
class DocumentView:ScrolledWindow
construct( document:TextBuffer )
var view = new TextView.with_buffer( document )
view.set_wrap_mode( Gtk.WrapMode.WORD )
this.add( view )
interface Command:Object
def abstract execute()
interface DocumentSelector:Object
def abstract select():bool
def abstract get_document():string
class Text:TextBuffer
construct ( initial:string = "" )
this.text = initial
class DocumentFileSelector:Object implements DocumentSelector
_parent:Window
_uri:string = ""
construct( parent:Window )
_parent = parent
def select():bool
var dialog = new FileChooserDialog( "Open file",
_parent,
FileChooserAction.OPEN,
dgettext( "gtk30", "_OK"),
ResponseType.ACCEPT,
dgettext( "gtk30", "_Cancel" ),
ResponseType.CANCEL
)
selected:bool = false
var response = dialog.run()
case response
when ResponseType.ACCEPT
_uri = dialog.get_uri()
selected = true
dialog.destroy()
return selected
def get_document():string
return "Reading the text from a URI is not implemented\n%s".printf(_uri)
class Load:Object implements Command
_receiver:TextBuffer
_document_selector:DocumentSelector
construct( receiver:TextBuffer, document_selector:DocumentSelector )
_receiver = receiver
_document_selector = document_selector
def execute()
if _document_selector.select()
_receiver.text = _document_selector.get_document()
A common high-level pattern for graphical user interfaces is model-view-controller (MVC). This is about de-coupling your objects so they can be easily re-used and changed. In the example document has become the object that represents the model. By making this a separate object it allows multiple views to be given of the same data. For example when writing a StackOverflow question you have an editor window, but also a pre-view. Both are different views of the same data.
In the example the header toolbar has been further separated into different objects using the command pattern. Each button in the toolbar has an associated command. By having the commands as separate objects the command can be re-used. For example the key binding Ctrl-O may also use the Load command. This way the code for the command attached to the open document button doesn't need to be re-written for attaching it to Ctrl-O.
The command pattern makes use of an interface. As long as an object implements the execute() method then it can be used as a command. The Load command also makes use of an interface for the object that asks the user which URI to open. Gtk+ also provides a FileChooserNative. So if you wanted to switch to using a FileChooserNative dialog instead of a FileChooserDialog you would just need to write a new object that implements the DocumentSelector interface and pass that to the Load command instead. By de-coupling objects in this way it makes your program much more flexible and the use of private fields are kept confined to each object.
As a side note, when compiling your example there were a few warnings: warning: Gtk.Stock has been deprecated since 3.10. The example in this answer uses the newer way:
for the open document icon the GNOME developer documentation for Stock Items states "Use named icon "document-open" or the label "_Open"." So I've used document-open. These names are from the freedesktop.org Icon Naming Specification
for the OK button in the file chooser dialog the GNOME Developer documentation states "Do not use an icon. Use label "_OK"." The underscore before means it is internationalised and translated by gettext. gettext uses 'domains' which are translation files. For GTK+3 the domain is called gtk30. To enable gettext when your program is compiled a macro for the default domain needs to be passed to the C compiler. This is why the -X -DGETTEXT_PACKAGE is needed. Also in the Genie program Intl.setlocale() is needed to set the locale to the runtime environment. When this is done using something like LC_ALL="zh_CN" ./text_editor_example to run your program will show the OK button in Chinese if you have that locale installed
Question
Considering these classes:
class BookCase { ArrayList<Book> books }
class Book { ArrayList<Page> pages }
class Page { String color }
And considering this natural language rule:
When all pages in a bookcase are black, do A
The trivial approach would be to nest forall clauses, but in Drools can't do that, because forall clauses only allow Patterns (not Conditional Elements, what a forall clause is) inside!
How do I express this in Drools then?
This is close, but not quite the right thing:
rule "all black pages"
when
BookCase( $books: books )
$book: Book( $pages: pages ) from $books
not Page( color != "black" ) from $pages
then
System.out.println( "doing A" );
end
The problem is that this will fire once for each book where all pages are black. To assess all pages in all books one could assemble a list of all pages and make sure they are all black:
rule "all black pages, take 2"
when
BookCase( $books: books )
$pages: ArrayList() from accumulate( Book( $ps: pages ) from $books,
init( ArrayList list = new ArrayList(); ),
action( list.addAll( $ps ); ),
result( list ) )
not Page( color != "black" ) from $pages
then
System.out.println( "doing A" );
end
You can actually nest multiple foralls if you don't use forall(p1 p2 p3...), but the equivalent not(p1 and not(and p2 p3...)). Then, to keep individual books and pages from firing the rule, chuck an exists in between there.
rule 'all pages in bookcase are black'
when
(and
$bookCase: BookCase()
(not (exists (and
$book: Book() from $bookCase.books
not( (and
not( (exists (and
$page: Page() from $book.pages
not( (and
// slightly different constraint than I used in question
eval($page.color == $book.color)
) )
) ) )
) )
) ) )
)
then
...
end
Unlike using accumulate to create a flat list of all pages, this will maintain the context of $page, that is, when a page is put in a constraint with its parent book as in the example above, in this solution Drools still 'knows' what the parent book is.
While I was writing the question, I think I found the answer myself:
BookCase($caseContents : books)
$bookWithOnlyBlackPages : ArrayList<Page>() from $caseContents
forall ( $page : Page(this memberOf $bookWithOnlyBlackPages)
Page(this == $page,
color == "black") )
forall ( $bookInCase : ArrayList<Page>(this memberOf $caseContents)
ArrayList<Page>(this == $bookInCase,
this == $bookWithOnlyBlackPages) )
I'm experimenting with Dynamic Data Lists in Liferay 6.1. The data definitions and list editors work fine, but I'm having trouble preparing a template to display the list. In particular I'm wondering how to implement sorting and pagination of the display, as the list eventually grows very long.
Let's start with ordering. Theoretically the template below should use the getRecords method which allows for an OrderByComparator ( http://bit.ly/MqsGNE ), but where is the factory, which would allow me to create the needed comparator?
#set ($ddlRecordsUtil = $serviceLocator.findService("com.liferay.portlet.dynamicdatalists.service.DDLRecordLocalService"))
#set ($recordSetId = $getterUtil.getLong($reserved_record_set_id.data))
## How to create an OrderByComparator which would ORDER_BY_text2132_DESC ??
#set ($orderBy = ???????????)
#set ($records = ${ddlRecordsUtil.getRecords($recordSetId,-1,-1,50, $orderBy)})
<ul>
#foreach ($record in $records)
#set ($name = $record.getField("text2132").getValue())
<li><em>${name}</em></li>
#end
</ul>
Am I missing something, is there another approach to sorting these lists before they are fetched from the database?
#set ($records = ${ddlRecordsUtil.getRecords($recordSetId,-1,-1,50,ORDER_BY_text2132_DESC)})
Try this, this will work.
I am making some changes to a site using ExpressionEngine, there is a concept I can't seem to quite understand and am probably coding workarounds that have pre-provided methods.
Specifically with channels and members, the original creator has added several custom fields. I am from a traditional database background where each column in a table has a specific meaningful name. I am also used to extending proprietary data by adding a related table joined with a unique key, again, field names in the related table are meaningful.
However, in EE, when you add custom fields, it creates them in the table as field_id_x and puts an entry into another table telling you what these are.
Now this is all nice from a UI point of view for giving power to an administrator but this is a total headache when writing any code.
Ok, there's template tags but I tend not to use them and they are no good in a database query anyway.
Is there a simple way to do a query on say the members table and then address m_field_1 as what its really called - in my case "addresslonglat".
There are dozens of these fields in the table I am working on and at the moment I am addressing them with fixed names like "m_field_id_73" which means nothing.
Anybody know of an easy way to bring the data and its field names together easily?
Ideally i'd like to do the following:
$result = $this->EE->db->query("select * from exp_member_data where member_id = 123")->row();
echo $result->addresslonglat;
Rather than
echo $result->m_field_id_73;
This should work for you:
<?php
$fields = $data = array();
$member_fields = $this->EE->db->query("SELECT m_field_id, m_field_name FROM exp_member_fields");
foreach($member_fields->result_array() as $row)
{
$fields['m_field_id_'.$row['m_field_id']] = $row['m_field_name'];
}
$member_data = $this->EE->db->query("SELECT * FROM exp_member_data WHERE member_id = 1")->row();
foreach($member_data as $k => $v)
{
if($k != 'member_id')
{
$data[$fields[$k]] = $v;
}
}
print_r($data);
?>
Then just use your new $data array.
I'm quite new to Drupal 6 and theming it. My theme required the main menu to pump out quite extensive html/css for my reasonably involved styling. To achieve this I pieced together this code 'function phptemplate_menu_item' (see bottom) which sits in my template.php and produces different html depending on the whether the menu item has children or not and uses the contents of the link to generate a css class.
My problem is that this code is also being applied to my other menus. I would like make the menu_item generate different html depending on whether it is in the primary-menu or not. I would have thought that the easiest way to do this is with an if statement in the function phptemplate_menu_item, for example:
function phptemplate_menu_item (...){
if ($menu_name == 'primary-links')
{DO ABC}
else
{DO XYZ}
}
However I believe I need to know how to pass the menu name to the phptemplate_menu_item function. Any help with this would be really appreciated as I have been banging my head against the wall trying to solve this for some time now.
Thanks!
function phptemplate_menu_item($link, $has_children, $menu = '', $in_active_trail = FALSE, $extra_class = NULL) {
$class = ($menu ? 'no_wrap' : ($has_children ? 'collapsed' : 'li_wrap'));
if (!empty($extra_class)) {
$class .= ' '. $extra_class;
}
if ($in_active_trail) {
$class .= ' active-trail';
}
if (!empty($link)) {
/* The following section gives the list items unique classes based on their link text - note how spaces and sepcial chars are removed */
// remove all HTML tags and make everything lowercase
$css_id = strtolower(strip_tags($link));
// remove colons and anything past colons
if (strpos($css_id, ':')) $css_id = substr ($css_id, 0, strpos($css_id, ':'));
// Preserve alphanumerics, everything else goes away
$pattern = '/[^a-z]+/ ';
$css_id = preg_replace($pattern, '', $css_id);
$class .= ' '. $css_id;
}
// the following code returns the menu item formatted in a different fashion depending on the class of the item. The first one is for items with a class of none - ie the space li at end of menu
if (strstr($class, 'none')) {
return '<li class="'. $class . ' main"></span></span></li>';
}
if (strstr($class, 'li_wrap')) {
return '<li class="'. $class .' main"><span class="wrapped">'. $link . $menu ."<span class='indicator'></span></li>\n";
}
if (strstr($class, 'no_wrap')) {
return '<li class="'. $class . ' main">'. $link ."<span class='indicator'></span><span class='menu_box'><span class='menu_box_inner'>". $menu ."</span></span></li>\n";
}
}
Well I think the solution found here it's the best so I'm not going to take credit for it. Instead of overwriting theme_menu_item you should define your custom function theme_primary_links starting from theme_links.You can choose whatever name you think it's best for your custom theme (but make sure that it's not already used).
Bottom line: sometimes it's easier to define your custom theme than overwriting the default ones. That way you know that you can strictly apply the custom theme according to your needs (e.g. applied only to the primary menu links). Overwriting is best used when you want your changes to be global (e.g. applied to all menu links).