The Wayback Machine - https://web.archive.org/web/20230325020621/https://github.com/cuberite/cuberite/pull/5003
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ability to register webadmin pages through Info.lua #5003

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

NiLSPACE
Copy link
Member

@NiLSPACE NiLSPACE commented Oct 17, 2020

This is just something I've thought about for years, but never had the time to actually make. I'd like to get other opinions on this.

I've always felt the way web pages are handled in Cuberite is less than ideal. I've had a few ideas on how to make it a bit better for years. Now I finally have the time to work on it.

Info.lua

With this PR you can define your webpages inside the Info.lua file:

	WebAdminPages = 
	{
		{
			Title = "Testpage",
			UrlPath = "TestpagePath",
			WebController = TestController,
		}
	}

Controllers

Inside the Info.lua you can define all the web pages, but instead of providing a callback function you can provide a class. This class inherits from WebControllerBase which i've created inside InfoReg.lua. This controller handles the web pages for a single page, but it can have multiple endpoints. The WebControllerBase class provides additional functionality to return json, files and views (more on that later).

Currently I have a really simple routing system in place. It takes the HTTP method and puts it in front of the actionname (default is Index). If I want to access a different endpoint I'd have to add a query parameter called action.

-- Inherit from WebControllerBase
TestController = setmetatable({}, {__index = WebControllerBase});
TestController.__index = TestController




-- Constructor for this controller
function TestController:new()
	local obj = setmetatable(WebControllerBase:new(), {__index = TestController});
	return obj;
end



-- Default endpoint.
function TestController:GETIndex(a_Request, a_Path)
	return self:view("testview", 
		{
			TextWhichCanContainHtml = "Hello there<script>alert('TEST')</script>", 
			numbers = { 0, 1, 2, 3, 4, 5, 6 }
		}
	);
end


-- Can be accessed using a get to ?action=Players.
-- Returns a json array containing all active players.
function TestController:GETPlayers(a_Request)
	local playerList = {};
	cRoot:Get():ForEachPlayer(function(a_Player)
		table.insert(playerList, a_Player:GetName());
	end);
	return self:json(playerList);
end


-- Kicks the requested user.
function TestController:POSTKickPlayer(a_Request)
	local playerToKick = a_Request.PostParams['player']
	local success = false;
	cRoot:Get():FindAndDoWithPlayer(playerToKick, function(a_Player)
		a_Player:GetClientHandle():Kick("Bye")
		success = true;
	end);
	return self:json({success = success});
end

Views

Returning the html code is, in my opinion, really clunky at the moment. This PR includes a really simple templating engine that allows you to write Lua code through html. The views are loaded from a subfolder called webviews inside the plugin's own folder. For example you can write code like this:

<table>
{={cRoot:Get():ForEachWorld(function(a_World)
	<>
		<tr>
			<td>
				</>{{a_World:GetName()}}<>
			</td>
		</tr>
	</>
end)}=}
</table>

It's also possible to pass variables from the controller to the view. For example, using the controller code above:

{{TextWhichCanContainHtml}}

<ul>
{={for i, number in ipairs(numbers) do
	<><li></> {{number}} <></li></>
end}=}
</ul>

Problems

Currently I'm struggling with a few things in this PR.

  • Errors in views are currently difficult to debug.
  • InfoReg.lua has to be loaded while creating your controllers if you want them to inherit from WebControllerBase. This means, to be safe, you'll have to use dofile in every file which contains a controller.

@NiLSPACE
Copy link
Member Author

Any thoughts about this?

@tigerw
Copy link
Member

tigerw commented Oct 18, 2020

Am I right in describing this as a higher-level abstraction over AddWebTab, for ease of use improvements?

@NiLSPACE
Copy link
Member Author

NiLSPACE commented Oct 18, 2020

Yes, exactly. It's an attempt to add some kind of MVC framework to the webadmin.

@tigerw
Copy link
Member

tigerw commented Oct 18, 2020

That makes sense, I'm not sure if InfoReg.lua is the right place for it though. It sounds like there's a potential to develop this into a separate project as a library in its own right. About the errors being difficult to debug, what's the issue? Is it something the C++ side can help improve?

@NiLSPACE
Copy link
Member Author

My idea was that if we use the InfoReg.lua file for this we could also automatically generate the webadmin pages into the plugin's generated documentation.

The errors are simply because currently I take the view, do some pattern-matching magic to it and turn it into lua bytecode using loadstring. Because of that line numbers might not match up with the original file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants