Scala Play: object index is not a member of package views.html - scala

I'm getting
object index is not a member of package views.html
but unlike all the other threads opened on this subject, my issue seems totally unrelated to the IDE. I get this issue from the command line (no IDE) no matter how much I try to clean and rebuild by running
activator clean compile run
or just
sbt clean compile
Here is my conf/routes:
GET / controllers.Application.index
GET /books controllers.Application.listBooks
POST /books controllers.Application.upload
GET /assets/*file controllers.Assets.at(path="/public", file)
This si my views/index.scala.html:
#import play.api.data.Form
#import models.Book
#(form: Form[Book])(implicit messages: Messages)
<!DOCTYPE html>
<html>
<head>
<title>xxx</title>
<link rel="stylesheet" type="text/css" media="screen" href='#routes.Assets.at("stylesheets/main.css")'>
<script type="text/javascript" href='#routes.Assets.at("javascripts/jquery-1.9.0.min.js")'></script>
</head>
<body>
<div class="screenshot">
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span>
</a> <a class="brand" href="#">Workday Dublin CTF</a>
<div class="nav-collapse">
<ul class="nav">
</ul>
</div>
</div>
</div>
</div>
<h1>All Your Books Are Belong To Us</h1>
<div class="container">
<h2>Add Book</h2>
#helper.form(action = routes.Application.upload, 'enctype -> "multipart/form-data") {
#helper.inputText(form("title"))
#helper.inputText(form("author"))
#helper.inputFile(form("myUpload"))
<div class="form-actions">
<button type="submit" class="btn btn-primary">Create Book</button>
</div>
}
</div>
</div>
</body>
</html>
Finally, here is where the error is thrown, in my controllers/Application.scala:
package controllers
import models.Book
import models.Book._
import play.api.mvc._
class Application extends Controller {
def index = Action {
Ok(views.html.index(Book.form))
}
def listBooks = Action {
Ok(books.head.myUpload)
}
def upload() = Action(parse.multipartFormData) { request =>
request.body.file("myUpload").map { myUpload =>
import java.io.File
val filename = myUpload.filename
val contentType = myUpload.contentType
myUpload.ref.moveTo(new File(s"/tmp/$filename"))
addBook(Book("xxxtitle", "xxxauthor", filename))
Ok("File uploaded at /tmp/"+filename)
}.getOrElse {
Redirect(routes.Application.index).flashing(
"error" -> "Missing file")
}
}
}
The error is thrown at Ok(views.html.index(Book.form)) which references models/Book.scala:
package models
import play.api.data.Form
import play.api.data.Forms._
case class Book(title: String, author: String, myUpload: String)
object Book {
var books = List(Book("title test 1", "author test 1", "filename test 1"))
def addBook(book: Book) = books = books ::: List(book)
val form = Form(mapping(
"title" -> text,
"author" -> text,
"myUpload" -> nonEmptyText)(Book.apply)(Book.unapply))
}
As I've researched a lot about this, and no other solution has worked so far, any help would be immensely appreciated. Thank you so much!

Delete all content from folder /project/target and build on terminal:
sbt compile

Apparently, even in this case the issue was related to the IDE. Despite seemingly unrelated, given it occurred from the command line and even after applying all the changes suggested by others.
I created a new project -> Play 2.x in IntelliJ IDEA 2016.2.2. Then I copy/paste all the content from the old faulty project, within in the new project structure. And everything worked straight away, although I had to add
import play.api.Play.current
import play.api.i18n.Messages.Implicits._
to Application.scala in order to pass the implicit messages (as #curious spotted in the comments). I did not mark his comment as the answer because when I tried to add these imports in the faulty project, I was still getting the same error. So nope, the fix would be something to do wth the IDE settings which I still am not too sure about. Surely my workaround is good enough for me, though.

Related

How do you extend templates in Leaf using the #extend and #export tags in leaf?

The Leaf documentation doesn't seem to be working for me I can't figure out why.
child.leaf
#extend("index"):
#export("hello"):
<p>Welcome to Vapor!</p>
#endexport
#endextend
index.leaf
<!-- Backend Projects -->
<div class="seciton-label">
<h3>#(.backendCollection.title)</h3>
</div>
#import("hello")
<!-- Backend Card -->
#for(card in .backendCollection.collection):
<div class="greeting-card">
<a href=#(card.url)>
<h3>#(card.title)</h3>
</a>
<p> #(card.description) </p>
</div>
#endfor
The following image is the result I get in localhost
Request result running the vapor server on localhost
Please help - I can't find solutions to this issue.
No response from forums.swift.org
Tried removing the import key
Removing quotes
I saw individuals using the following format in older versions of Vapor. This did not work for me either.
<!-- I tried the following format for the extend and export blocks -->
#extend("index") {
#export("hello") {
<p>Welcome to Vapor!</p>
}
}
I'm trying to be able to extend the leaf templates and understand why the html does not render.
This works and does something similar to what you want.
This is my 'template' (heavily simplified here), called Base.leaf:
<!DOCTYPE html>
<html>
<head>
<title>#(title)</title>
</head>
<body>
#import("body")
</body>
</html>
#extend("Build/Message")
</body>
</html>
The extend of Build/Message above behaves simply like an include.
Then I use it in a form called Login.leaf here:
#extend("Build/Base"):
#export("body"):
<form method="POST" action="/log-in">
<label for="email">Email</label>
<input type="text" name="email" required>
<label for="password">Password</label>
<input type="password" name="password" required>
<button class="btn-success">Log-in</button>
</form>
#endexport
#endextend
I then use the `Login.leaf' in a render such as:
let context = ["title": "Log in", "version": C.Msg.Version, "message": request.getMessage()]
return try await request.view.render("Form/Login", context)

How do I find second div class with the same name?

I don't even know how to properly ask this.
I just started with python, and I'm trying to make a crawler.
Everything works fine but I can't "call" or "find" the second div with identical class names in the body.
I've been searching internet for help but the way people write their code is not similar to what I wrote.
so the HTML looks something like this:
<div class="card">
<div class="card-body">...</div>
<div class="card-body">...</div>
My code:
comp_link = comp_card.find('a', class_ = 'link')
href_link = comp_link['href']
link_final = 'https://www.someweb.com' + href_link
prof_text = requests.get(link_final).text
prof_soup = BeautifulSoup(prof_text, 'lxml')
comp_name = prof_soup.find('h2', class_ = 'company-name').text.strip()
comp_info = prof_soup.find('div', class_ ='col-md-12 col-lg-4')
but when I try to use
comp_info = comp_info.find('div', class_ = 'card-body'[1])
it doesn't work.
I've tried to experiment, use other peoples solutions from StackOverflow (but I'm too dumb).
Often, I prefer using CSS selectors. In this simple case you could select the second child that has the class name card-body. You can use the nth-child selector to grab the second div:
import bs4
html = """
<div class="card">
<div class="card-body">Not this</div>
<div class="card-body">But this</div>
</div>
"""
soup = bs4.BeautifulSoup(html)
print(soup.select('div.card-body:nth-child(2)'))
Output
[<div class="card-body">But this</div>]
If you happen to be in a situation where the targetted element is not actually the second element, but simply the second element with the class card-body, it may be advantagous to use nth-child(n of selector). This will select the second one element that matches the specified selector:
html = """
<div class="card">
<div class="other-class">Not this</div>
<div class="card-body">Or this</div>
<div class="card-body">But this</div>
</div>
"""
soup = bs4.BeautifulSoup(html)
print(soup.select('div:nth-child(2 of .card-body)'))
Output
[<div class="card-body">But this</div>]
BeautifulSoup's CSS selector logic is driven by the SoupSieve library, and more information can be found here: https://facelessuser.github.io/soupsieve/selectors/pseudo-classes/#:nth-child.

How to properly use JSExport methods in a JSExportTopLevel object in Scala.js from a <script> tag?

I have some sjs code:
#JSExportTopLevel("CCRS")
object JsApi {
#JSExport
def makeJobId: JobId = JobId()
// ...
}
I have the following <body> element, which I'll note is properly finding the sjs-generated .js files since I was using a 3rd party SPA framework previously - though the launcher for that is now commented out:
<body>
<script type="application/javascript" src="ace/ace.js" charset="utf-8"></script>
<script type="application/javascript" src="target/web-client-jsdeps.js"></script>
<script type="application/javascript" src="target/web-client-opt.js"></script>
<!-- <script src="target/web-client-launcher.js"></script> -->
<input type="text"
placeholder="Enter a command:"
value="pwd"
onkeydown="oneShotHandler()" />
<div id="one-shot-demo"></div>
<script type="application/javascript">
var oneShotId = CCRS.makeJobId();
</script>
</body>
Upon page load, I get the following error: TypeError: CCRS.makeJobId is not a function.
Not really sure what I should be looking for in the generated web-client-opt.js file (using sjs 0.6.22 currently, with -P:scalajs:sjsDefinedByDefault). But, I do see this line, which I believe should be doing the export:
$e.CCRS = $m_Lorg_xsede_jobrunner_client_JsApi$();
I realized this just as I was finishing typing my question. The beauty of talking it out.
In Scala.js, I needed to add the () to my method:
#JSExport
def makeJobId(): JobId = JobId()

AEM 6.3 - Sling Model not working

I am using a very basic Sling Model class which is not working at all. This is the class:
package com.aem.sites.models.test;
import org.apache.sling.models.annotations.Model;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct;
import org.apache.sling.api.resource.Resource;
#Model(adaptables=Resource.class)
public class TestModel {
final static Logger logger = LoggerFactory.getLogger(TestModel.class);
private String email;
#PostConstruct
public void init() {
logger.info("=====================================================================inside init method");
email = "something#something.com";
}
public String getEmail() {
return email;
}
}
I have also included the package in the section like this:
I also looked for the Sling Model class here http://localhost:4502/system/console/status-adapters
and found it's entry like this:
Adaptable: org.apache.sling.api.resource.Resource
Providing Bundle: org.apache.sling.models.impl
Available Adapters:
* com.aem.sites.models.test.TestModel
What's more surprising to me is the Sling Model class in the package com.aem.sites.models.header is being called properly.
I don't know what's wrong.
Thanks in advance
Sharing the HTL class:
<sly data-sly-use.bannerObj=com.aem.sites.models.test.TestModel">
<section id="banner"
style="background-image: url('/content/dam/aem-site/banner.jpg')">
<div class="inner">
<h2>Today's temperature is</h2>
<p>
${bannerObj.email}
</p>
<ul class="actions">
<li>Sign Up</li>
<li>Learn More</li>
</ul>
</div>
</section>
</sly>
By not working I mean nothing is happening. No errors or any logs are appearing in the error.log file.
The only issue I see is a syntax error, the data-sly-use attribute's value is not enclosed in quotes properly.
<sly data-sly-use.bannerObj="com.aem.sites.models.test.TestModel">
<section id="banner"
style="background-image: url('/content/dam/aem-site/banner.jpg')">
<div class="inner">
<h2>Today's temperature is</h2>
<p>
${bannerObj.email}
</p>
<ul class="actions">
<li>Sign Up</li>
<li>Learn More</li>
</ul>
</div>
</section>
</sly>
Due to which the HTL file might not have compiled and would have output the entire HTL as is without compiling.
You can check from http://localhost:4502/system/console/status-slingmodels which Sling models are available in your instance and to what resources they are bound.
I would make sure my models are listed and then check for other kind of errors, like typos as mentioned in the comment above.

Flash doesn't show any message

I have a _flash subtemplate:
#(flash: Flash)
#flash.data.foreach { x =>
#x._1, #x._2
}
This code never shows any flash message. The code below doesn't work either
#if(!flash.isEmpty) {
#for((msgKey, msgValue) <- flash) {
<div class="alert alert-#msgKey" data-dismiss="alert">
<a title="#Messages("misc.message.close")" class="close">×</a>
#msgKey
</div>
}
}
due to the error at runtime: filter is not a member of Flash. And oddly enough, the code below does work and show a message:
#flash.get("success")
How I set the message is not important because it works well in the last case, however, there is the code for it:
if (success) {
Redirect(routes.Application.success).flashing("success" -> "Ok123")
} else {
Ok(views.html.registration.add(newForm))
}
My aim is loop over flash because it want to show all messages in _flash subtemplate.
UPDATE: I realized why the first approach doesn't work (I have to use map instead). But why does the second one raise the error at runtime?
Syntax error, you missed flash.data. From Play 2.0 API we see that Flash is a
case class Flash (data: Map[String, String]) extends Product with Serializable
So the correct code should be:
#if(!flash.isEmpty) {
#for((msgKey, msgValue) <- flash.data) {
<div class="alert alert-#msgKey" data-dismiss="alert">
<a title="#Messages("misc.message.close")" class="close">×</a>
#msgKey
</div>
}
}
I'm almost sure that this is compile-time error, you see it in runtime only because you use dev mode.
BTW, I usually do something like this:
#()(implicit flash: play.api.mvc.Flash)
#flash.get("success").map { message =>
<div class="alert alert-success alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
#message
</div>
}
#flash.get("failure").map { message =>
<div class="alert alert-danger alert-dismissable">
<a class="close" data-dismiss="alert">×</a>
#message
</div>
}