Where to place widgets in Yii2 application - yii2

I'm using Yii2 to create my application. I also like to use the widget feature, but I'm not sure, what is the best practice for the widget code location. The Yii2 directory-structure provides 2 directories:
#app/components
#app/widgets
The location "2." (#app/widgets) sounds like the best location for widgets. But, the Yii2 documentation for widgets used the location "1." (#app/components)
So my question: what is the right place for own widgets?

I put it in #app/components/*.
There I also put
#app/components/widgets/*
#app/components/helpers/*
#app/components/validators/*
#app/components/otherComponent/*
#app/components/MyActiveRecord.php
#app/components/MyController.php
and other components of my application

Related

Is it possible to load a specific 2sxc module in a DNN skin?

DNN Platform 9.3.2 /
2sxc 10.25.2
I have a DNN website that uses 2sxc. I created a "Notification Bar" content type and c# razor template that I use to display special notifications to the user. This module is meant to display on every single page of the website. I used the "Add Existing Module" functionality to manually add the module to every page but it's a bit cumbersome and I run the risk that my Content Editors move the module by accident, delete, or forget to add it to new pages.
Is there a special 2sxc skin object that I can use inside of my .ascx DNN skin to load a 2sxc module so that I don't have to add it to every page through DNN? Apparently there is one in DNN OpenContent.
(More than just the notification bar, this would be super useful for the site's header or footer that gets occasionally updated. For example, social media links, contact info like address or phone number, or other links that aren't part of the DNN pages menu.)
There are two ways
create a pane for this specific module (it's the easiest to edit and work with) and just show the module on all pages
create the module on a hidden page and then inject it into the skin, using the Factory to get the CmsBlock - see https://docs.2sxc.org/api/dot-net/ToSic.Sxc.Dnn.Factory.html#ToSic_Sxc_Dnn_Factory_CmsBlock_System_Int32_System_Int32_
Daniel, this is how we did it in the past. I notice your call is similar but simpler (above in the comments). Is that because the API changed somewhere after v10?
<script runat="server">
// get 2sxc to Render() the output from the module on the SITE/Manage Flyout Links page
private IHtmlString RenderFlyoutMenu()
{
return ToSic.SexyContent.Environment.Dnn7.Factory.SxcInstanceForModule(3354, 606).Render();
}
</script>
<%=RenderFlyoutMenu() %>

routing between angularJs and playframework

I'm working with restangular ngroute and playframework and I'm trying to do my CRUD following this tutorial : http://plnkr.co/edit/d6yDka?p=info
the list.html and detail.html in the index page (in the tutorial), I have them all in customer.scala.html page which call the main page by using this : #main("MyApp") So all my controllers and models are defined in this main page.
So how can I do the routing, the way that when I click on a button I can call the link (localhost:9000/custd) definded here in my js page:
app.config(function($routeProvider, RestangularProvider) {
$routeProvider.
when('/custd', {
controller:ListCtrl,
templateUrl:'list.html'
}).
UPDATE:
this is the link in customer.scala.html
<li>Customers</li>
in the file Application.scala I have this:
def custDetail = Action {
Ok(views.html.custDetail("Your new application is ready."))
}
in routes I have this:
GET / controllers.Application.index
GET /custdetail controllers.Application.custDetail
so how can I link this : /custd (in the angular controller) with my html page
So I think you're jumping in at the deep end a bit here. If you don't understand how to make a simple play web app, and you don't understand how to make a simple angular app then it might not be the best idea trying to integrate both straight away (I tried the same thing when I was new to this and it was complicated!).
Why have you chosen Angular for this given job? If you are not planning to create a single page application (which it sounds like you're not), then just using play templating should be sufficient for your needs (ands there's lots of docs available!).
If you are adamant on using the two, angular routing is geared towards angular applications. Looking at the routing you've provided:
app.config(function($routeProvider, RestangularProvider) {
$routeProvider.
when('/custd', {
controller:ListCtrl,
templateUrl:'list.html'
}).
In this you have provided a controller and a template. These are in reference to Angular controllers html templates, not Play. If you're not sure on how Angular controllers work, Angular has great documentation:
https://docs.angularjs.org
You need to work out exactly what information you need from the server side, create an endpoint to serve that data to your Angular app (using AJAX calls). I know this is a high level answer but really integrating the two is quite complex and hard to summarise in a single reply. My advice would be focus on creating an Angular OR Play app, then once you have the basics down move to integrating the two, but be clear as to the reasons behind chosing your technology as it sounds like you may not be

Get an absolute link from a relative one in Freemarker

I'm creating a site using Magnolia - CMS. Now I am implementing a blog page. On each blog page, there are several share buttons. Now I'm busy implementing the twittershare button. Here I am going to use the twitter cards. For that, I need to provide the URL of an image in a metatag. Main problem: I retreive my image like this: ${damfn.getAssetLink(content.blogImage)}. This only returns a relative path to my resource. Is there a quick way (in freemarker), that will convert tis to an absolute link?
Many thanks in advance!
usually you define magnolia.default.base.url in the magnolia.properties.
then you can retrieve it with Components.getComponent(ServerConfiguration.class).getDefaultBaseUrl()
now you have to install the service into freemarker. you can do that by adding installer-tasks into the renderers on startup. you do that in your module-version-handler. there you overwrite the getStartupTasks(...), something like this:
#Override
protected List<Task> getStartupTasks(InstallContext installContext) {
final List<Task> tasks = new ArrayList<>();
tasks.add(new InstallRendererContextAttributeTask("rendering", "freemarker", "serverConf", ServerConfiguration.class.getName()));
tasks.add(new InstallRendererContextAttributeTask("site", "site", "serverConf", ServerConfiguration.class.getName()));
return tasks;
}
now you can call in freemarker:
"${serverConf.defaultBaseUrl}/${ctx.contextPath}/${damfn.getAssetLink(content.blogImage)}"
checkout if the slashes are necesarry and make sure that defaultBaseUrl is set properly in your magnolia configuration ("/server/...")
edit: there should be an easier by calling the current request in freemarker ${Request} so it could be something like "${Request.domain}/${ctx.contextPath}/${damfn.getAssetLink(content.blogImage)}" without injecting the serverConfiguration into the renderer

Path resolution in Web application when AngularJs is accessing and MVC4 server

I am trying to create a modular applications by mixing the ASP.Net MVC4 and AngularJS. what MVC does is that it allows us to have a path separation like below.
Home screen
http://127.0.0.1:81/
when a user logs in, i provide them with a base path as below
`http://127.0.0.1:81/shipper/#/operations/home`
or
`http://127.0.0.1:81/client/#/orders/home`
so I get a base screen template per type of user and from then on it is a SPA that takes over on the template which sometimes share a common view based om the need.
now the issue i am having is that when i have to reference any server object like image on the web server that are all located in the root\themes\images\image1.jpg
the image URI in the fiddler is getting resolved to http://127.0.0.1:81/client/themes/images/image1.jpg
instead of
http://127.0.0.1:81/themes/images/image1.jpg
which obviously means this will fail.
my HTML looks like below:
<img class="media-object" src="themes/images/img180x120.png" />
is there a way I can override this to force it to ignore the /shipper or /client from the path ?
Regards, Kiran
As i turns out just preceeding the url with a / will make it a path relative the the host server.

AngularJS, Persistent (header) controller and specific (body) controller in one app

I am developing an HTML 5 mobile angular app with an android style skin. The app will need to be login-aware and I'm looking for advice on best practices. What I need is:
To have a persistent header that will display the current view, change the current view (via a dropdown), and perform login-specific functions (like "view my stuff" or "logout")
To have several different views within the app such as "master view" and "detail view" and "map view"
To have the app display a particular view (login.html) when the user is not logged in.
It seems like 3 is a special case of 1. In any case, the header is persistent throughout the app (except when a user isn't logged in) and the views will change based on user input. What is the best way to tackle this style of application using angular?
I think you want to use ngInclude.
I think you're already using ng-view for your body. Makes things easy :
<body>
<div id="header" ng-include="'header.html'"></div>
<div id="container" ng-view></div>
</body>