This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
151
Off-topic / Handy JS plugin
« on June 23rd, 2012, 07:26 PM »152
Off-topic / The 10 Year Sigh
« on June 11th, 2012, 05:21 AM »
So, some of you will be aware that recently my partner and I split up, and it emotionally and mentally screwed me up more than I want to admit to myself, but there you go.
Thing is, as much as it's turned my life upside down, I'm not entirely sure it hasn't done me a favour. I spent the better part of the evening butting heads with a jerk, acting something like a jerk myself, eh, that's life for you. Everything I dished out, I felt justified in.
But you know what? As justified as I've felt with everything I've done, there's something very wrong with me and my life right now. I've lost sight of what I got into this computing lark for. I've lost that spark, whatever it was, that made everything so awesome.
Everything of the last few weeks, certainly, but quite possibly a lot longer, has been walking a road almost for the sake of walking the road. None of the code I've turned out lately has been particularly wonderful, or interesting, or indeed particularly bug free, and it's just been a circle of fighting with it, unsatisfied and unfulfilled.
The me of 10 years ago understood. Me 10 years ago understood about making things because it was cool to make things, and whether anyone read it or not, it didn't matter, it was just cool to do, a great learning experience. Everything I did 10 years ago seemed deep and full of imagination - of course in hindsight it looks childish and primitive, but the me of 10 years ago didn't care.
The feeling of not seeing the wood for the trees, that's where I am right now. I'm so deep into code that I don't even understand why I'm doing it any more - not just this project or that project, but code as a thing. It's like a splinter in my mind, it consumes me, and I stopped understanding why I gave myself to it as I did.
So I sit here, just before I go to bed, about to knock back another rum+coke, I gotta wonder, where did I lose myself? Where did the magic go? Can I find it again? I hope so, but on that thought, I bid you good day.
I'm gonna take a few days out and see what I can do, see if I can find some of the magic I used to have. See you on the flipside.
Thing is, as much as it's turned my life upside down, I'm not entirely sure it hasn't done me a favour. I spent the better part of the evening butting heads with a jerk, acting something like a jerk myself, eh, that's life for you. Everything I dished out, I felt justified in.
But you know what? As justified as I've felt with everything I've done, there's something very wrong with me and my life right now. I've lost sight of what I got into this computing lark for. I've lost that spark, whatever it was, that made everything so awesome.
Everything of the last few weeks, certainly, but quite possibly a lot longer, has been walking a road almost for the sake of walking the road. None of the code I've turned out lately has been particularly wonderful, or interesting, or indeed particularly bug free, and it's just been a circle of fighting with it, unsatisfied and unfulfilled.
The me of 10 years ago understood. Me 10 years ago understood about making things because it was cool to make things, and whether anyone read it or not, it didn't matter, it was just cool to do, a great learning experience. Everything I did 10 years ago seemed deep and full of imagination - of course in hindsight it looks childish and primitive, but the me of 10 years ago didn't care.
The feeling of not seeing the wood for the trees, that's where I am right now. I'm so deep into code that I don't even understand why I'm doing it any more - not just this project or that project, but code as a thing. It's like a splinter in my mind, it consumes me, and I stopped understanding why I gave myself to it as I did.
So I sit here, just before I go to bed, about to knock back another rum+coke, I gotta wonder, where did I lose myself? Where did the magic go? Can I find it again? I hope so, but on that thought, I bid you good day.
I'm gonna take a few days out and see what I can do, see if I can find some of the magic I used to have. See you on the flipside.
153
Features / Need some help on a UI matter
« on June 10th, 2012, 12:22 AM »
OK, so I've been wrestling with a new feature and it's been annoying me because I can't find a UI I actually like. Let me explain - maybe something will occur to you, maybe you'll hate the idea entirely (in which case I'd love to hear an alternative)
I want to gut the current warning system to something more powerful, and in so doing I want to have it set up so that you can warn people and do things selectively.
So that you can remove a user's avatar, signature, moderate their posts, prevent them from posting, prevent them from logging in, and a few other things. The problem is how to manage all those options, it's bad enough with the three levels of moderation as it stands and this would make it worse.
So in response, I sat down with a couple of colleagues of mine who know far more about good UI than I do and thrashed it out and what we came up with is that you could turn on/off each type of sanction, then set a minimum level of % warning for it to be applied at, and then some control as to who would be able to apply that sanction.
So, for example, the default might be:
* Remove user avatar (off by default)
* Remove user signature (off by default)
* Moderate all users posts (available at 35% warning, any moderator can apply)
* Prevent user from posting (available at 60% warning, any moderator can apply)
* Prevent user from logging in (available at 80% warning, admins only)
Then in the issue warning area, you'd have the slider as currently, but instead of it telling you what action would happen, you'd get tickboxes to apply that sanction at the relevant % warning, so if you had an issue at 0% warning, there would be no options, but give them a 40% warning, and you'd have a tickbox to activate moderation.
If you were an admin and pushed it straight to 100%, you'd get all the options (moderation, post ban, full ban)
The issue warning screen is easy enough but I can't figure out how to make the admin screen not look like a mess. Or, for that matter, how to set it up as being anything other than 'admins' or 'anyone who can issue a warning' as the choices for who can apply certain sanctions.
Oh, and by the way, do note that I have a few ideas I'm not sharing here just yet for other things that can be done to user accounts (so we're not just talking the aforementioned half a dozen options or so, but it's realistically nearer to 10, so it needs to be quite lean), you'll understand why I'm not sharing when it's done, I don't want to influence anyone on a side track as to the options for dealing with troublemakers, the point here is to nail down the user interface side of it.
Would appreciate some thoughts on this.
I want to gut the current warning system to something more powerful, and in so doing I want to have it set up so that you can warn people and do things selectively.
So that you can remove a user's avatar, signature, moderate their posts, prevent them from posting, prevent them from logging in, and a few other things. The problem is how to manage all those options, it's bad enough with the three levels of moderation as it stands and this would make it worse.
So in response, I sat down with a couple of colleagues of mine who know far more about good UI than I do and thrashed it out and what we came up with is that you could turn on/off each type of sanction, then set a minimum level of % warning for it to be applied at, and then some control as to who would be able to apply that sanction.
So, for example, the default might be:
* Remove user avatar (off by default)
* Remove user signature (off by default)
* Moderate all users posts (available at 35% warning, any moderator can apply)
* Prevent user from posting (available at 60% warning, any moderator can apply)
* Prevent user from logging in (available at 80% warning, admins only)
Then in the issue warning area, you'd have the slider as currently, but instead of it telling you what action would happen, you'd get tickboxes to apply that sanction at the relevant % warning, so if you had an issue at 0% warning, there would be no options, but give them a 40% warning, and you'd have a tickbox to activate moderation.
If you were an admin and pushed it straight to 100%, you'd get all the options (moderation, post ban, full ban)
The issue warning screen is easy enough but I can't figure out how to make the admin screen not look like a mess. Or, for that matter, how to set it up as being anything other than 'admins' or 'anyone who can issue a warning' as the choices for who can apply certain sanctions.
Oh, and by the way, do note that I have a few ideas I'm not sharing here just yet for other things that can be done to user accounts (so we're not just talking the aforementioned half a dozen options or so, but it's realistically nearer to 10, so it needs to be quite lean), you'll understand why I'm not sharing when it's done, I don't want to influence anyone on a side track as to the options for dealing with troublemakers, the point here is to nail down the user interface side of it.
Would appreciate some thoughts on this.
154
Features: Upcoming / Q&A enhancement: multiple answers and multiple languages
« on May 31st, 2012, 02:32 PM »
After we had some... interesting... comments regarding the Q&A at Noisen, I figured I'd solve it once and for all.
So here's what I'm currently working on, making the anti-spam Q&A support multiple languages and support multiple answers. The UI's the first part I'm tackling and so far this is where I'm up to. It's not quite as pretty as it could be, but it certainly seems to be coming together.
So here's what I'm currently working on, making the anti-spam Q&A support multiple languages and support multiple answers. The UI's the first part I'm tackling and so far this is where I'm up to. It's not quite as pretty as it could be, but it certainly seems to be coming together.
155
Other software / PHP 5.4 bug, mods/plugins with hooks
« on May 27th, 2012, 03:17 PM »
So, I've been watching this for a while, ever since I heard that PHP 5.4 would deprecate call-time pass-by-reference, knowing full well that both SMF and Wedge's hook caller uses this.
I was not surprised to discover there were issues, nor was I surprised to note what the issues were, and now that I think about it, I was not surprised to note that my observation was entirely correct.
OK, here's the deal. When a hook is called, normally all the variables are shoved through call_user_func_array by reference. As of PHP 5.4, that won't work as expected.
Specifically, it won't work if the receiving function's signature doesn't state it's expecting things as references. Which meant that most of the mods written using hooks actually didn't work properly under PHP 5.4, though oddly enough this was never an issue for mine, because I always indicated everything should be by-reference anyway in the signatures, I found it a good practice to get into.
What that also means we should probably strip all the & signs from call_hook calls, because in both 5.3 and 5.4, the function's signature should be indicative of receiving-by-reference and in both cases it should be honoured.
In any case, any plugin using hooks should note that all variables received, that are intended to be modified in place should be indicated in the function xyz() definition as function xyz(&$variable) not function xyz($variable).
I was not surprised to discover there were issues, nor was I surprised to note what the issues were, and now that I think about it, I was not surprised to note that my observation was entirely correct.
OK, here's the deal. When a hook is called, normally all the variables are shoved through call_user_func_array by reference. As of PHP 5.4, that won't work as expected.
Specifically, it won't work if the receiving function's signature doesn't state it's expecting things as references. Which meant that most of the mods written using hooks actually didn't work properly under PHP 5.4, though oddly enough this was never an issue for mine, because I always indicated everything should be by-reference anyway in the signatures, I found it a good practice to get into.
What that also means we should probably strip all the & signs from call_hook calls, because in both 5.3 and 5.4, the function's signature should be indicative of receiving-by-reference and in both cases it should be honoured.
In any case, any plugin using hooks should note that all variables received, that are intended to be modified in place should be indicated in the function xyz() definition as function xyz(&$variable) not function xyz($variable).
156
The Pub / Some admin options required
« on May 22nd, 2012, 01:21 AM »
OK, there's a few things that need discussion since I'm not sure how best to cope with it. Some of it is just a to-do list, some of it needs discussion.
1. Thoughts
There are no configurable permissions for it at present, nor is there any way to disable it. Required permissions: add thought, edit (own/any) thoughts, delete (own/any) thoughts, reply to (own/any) thoughts.
2. Likes
There are no permissions for likes, nor any ability to disable it. I'm thinking that we also want options for whether likes are enabled or disabled, whether people can like their own posts or not and whether likes are only for the first post (i.e. liking the topic) or not.
3. Feeds
There's no way to have feeds active but disable the feed block in the sidebar. Do we need an option for that somewhere?
4. Quick access
There's no option to disable that. I'm thinking it might be a useful option. Also, might be nice to offer a hook for extending it so that plugins can add other areas to it.
1. Thoughts
There are no configurable permissions for it at present, nor is there any way to disable it. Required permissions: add thought, edit (own/any) thoughts, delete (own/any) thoughts, reply to (own/any) thoughts.
2. Likes
There are no permissions for likes, nor any ability to disable it. I'm thinking that we also want options for whether likes are enabled or disabled, whether people can like their own posts or not and whether likes are only for the first post (i.e. liking the topic) or not.
3. Feeds
There's no way to have feeds active but disable the feed block in the sidebar. Do we need an option for that somewhere?
4. Quick access
There's no option to disable that. I'm thinking it might be a useful option. Also, might be nice to offer a hook for extending it so that plugins can add other areas to it.
157
The Pub / Reminders, CAPTCHAs and registered users
« on May 15th, 2012, 11:03 PM »
OK, so I thought about implementing a CAPTCHA for the reminder widget. It is a method of identifying email addresses - and it never gets trapped by the error handler anywhere - and ultimately something that's going to limit the points of intrusion can only be a good thing.
So I started looking at the code and something odd about action=reminder struck me: it still works for logged in members too. Now this is really weird because I'm not sure it isn't a bug, but I'm not sure it isn't intentional behaviour either.
Let me explain. If you hit up action=reminder, you get thrown into the reminder handler, which has a bunch of subactions. But if no subaction is given, it will actually load the 'please give us the username or email address' prompt, due to no specified subaction, the relevant template being loaded and then hitting up template_main from Reminder.template.php.
That part seems half like an oversight, but the more I play around with it, the more I'm not sure about it being one. It seems almost fortunate that it happens to fall into the main reminder template (as opposed to other places, i.e. almost everywhere, where it explicitly sets the subaction if no valid one was found or none was supplied), but I don't see any 'is_guest' checks.
Then it hit me. You can't change your own password if you don't know your current one - and there's no way in the profile area to change your own password directly if you have forgotten it, meaning if you did want to change anything, you'd have to go through the reminder section - and it would let you, though whether you should be able to do so is debatable.
So, there's the question: should you be able to call the reset-password stuff if you're logged in, and if not, how should you be able to reset it from inside the profile area, since you can't change your password if you can't remember your current one?
It's a tricky one, but something that occurs to me. (Of course, I could just ignore it, implement the CAPTCHA anyway, and just not bother if the user is a registered member at the point of filling in the form)
So I started looking at the code and something odd about action=reminder struck me: it still works for logged in members too. Now this is really weird because I'm not sure it isn't a bug, but I'm not sure it isn't intentional behaviour either.
Let me explain. If you hit up action=reminder, you get thrown into the reminder handler, which has a bunch of subactions. But if no subaction is given, it will actually load the 'please give us the username or email address' prompt, due to no specified subaction, the relevant template being loaded and then hitting up template_main from Reminder.template.php.
That part seems half like an oversight, but the more I play around with it, the more I'm not sure about it being one. It seems almost fortunate that it happens to fall into the main reminder template (as opposed to other places, i.e. almost everywhere, where it explicitly sets the subaction if no valid one was found or none was supplied), but I don't see any 'is_guest' checks.
Then it hit me. You can't change your own password if you don't know your current one - and there's no way in the profile area to change your own password directly if you have forgotten it, meaning if you did want to change anything, you'd have to go through the reminder section - and it would let you, though whether you should be able to do so is debatable.
So, there's the question: should you be able to call the reset-password stuff if you're logged in, and if not, how should you be able to reset it from inside the profile area, since you can't change your password if you can't remember your current one?
It's a tricky one, but something that occurs to me. (Of course, I could just ignore it, implement the CAPTCHA anyway, and just not bother if the user is a registered member at the point of filling in the form)
158
Plugins / Crazy plugin-related idea I just had
« on May 15th, 2012, 04:26 AM »
OK, so I was contemplating how an arcade plugin might work, and in particular adding new games to one - as plugins themselves that depend on the main arcade.
And here's the weird thing, it occurs to me that we could do something truly neat.
As you know, the plugin manager works by the plugin-info.xml files, and the different XML indicates various things - there are XML tags for adding new bbcode, for adding scheduled tasks, and so on. What if a plugin could declare its own extra XML handlers?
So like the arcade plugin, it could declare a <arcade-game> block handler, so that arcade games could be bundled into plugins quickly and easily without having to do complex database changes or anything, just declare new items and let the arcade handler figure out what it wants to do with it.
In reality all we're really talking about is a hook in the enable/disable plugin routines that also passes the manifest SimpleXML object and plugins can register a hooked function for there. I don't think many would use it but it is certainly an interesting idea.
And here's the weird thing, it occurs to me that we could do something truly neat.
As you know, the plugin manager works by the plugin-info.xml files, and the different XML indicates various things - there are XML tags for adding new bbcode, for adding scheduled tasks, and so on. What if a plugin could declare its own extra XML handlers?
So like the arcade plugin, it could declare a <arcade-game> block handler, so that arcade games could be bundled into plugins quickly and easily without having to do complex database changes or anything, just declare new items and let the arcade handler figure out what it wants to do with it.
In reality all we're really talking about is a hook in the enable/disable plugin routines that also passes the manifest SimpleXML object and plugins can register a hooked function for there. I don't think many would use it but it is certainly an interesting idea.
159
Plugins / Random idea for a plugin
« on May 5th, 2012, 03:58 AM »
Just occurred to me. We could have a button that says "I'm having a drink" and you press it every time you start a new bottle of beer, and it records roughly how much alcohol you'd had.
Then it attaches a flag to each post written while drunk to say 'I was pissed while writing this' and the alcohol count goes down over time, so as you sober up you can look back and see what you wrote while pissed and others can forgive you if you wrote something stupid while drunk.
Then it attaches a flag to each post written while drunk to say 'I was pissed while writing this' and the alcohol count goes down over time, so as you sober up you can look back and see what you wrote while pissed and others can forgive you if you wrote something stupid while drunk.
* Arantor was a bit drunk while writing this.
Posted: May 5th, 2012, 03:57 AM
* Arantor had tongue firmly in cheek when writing, btw. This is not a serious idea. But it is an idea. Have at it.
160
Plugins / CAPTCHA plugins
« on May 4th, 2012, 05:12 PM »
So we have reCAPTCHA and what feels like a jillion other CAPTCHAs.
I already did a reCAPTCHA plugin and I can see other people will want others, so I'm curiously wondering... which is better? Do I implement one plugin that supports all of them (in a single main package) or do I implement each one with its own plugin?
I already did a reCAPTCHA plugin and I can see other people will want others, so I'm curiously wondering... which is better? Do I implement one plugin that supports all of them (in a single main package) or do I implement each one with its own plugin?
* Arantor is just curious, really.
161
Off-topic / So, busy out here in RL
« on May 2nd, 2012, 12:50 AM »
I thought I'd share some of my frustrations with you all.
I won't get into the detail of it but the last few days I've been snowed under - as I mentioned briefly - in building an app using Node.js, Express, Socket.io and MongoDB. I'm not going to explain what the app is, hopefully you'll see soon enough, but it's certainly been an interesting experience for me so far, and I feel like sharing what I've found.
First up, for those of who aren't familiar with Node.js, let me explain. We here are far more used to deploying apps where we have a web server like Apache, which receives requests, passes some of them onto PHP to process the contents of the page, and handles the page until it's ready and sends it back to the user.
It's convenient, practical and we're all used to it, but the app I've been working on lately requires longlife connections, what we would normally consider to be Comet style. I could have done it in AJAX but Comet is far less vicious on the server, especially given the real-time nature of the app in question, but in Apache/PHP this just is not practical.
Enter, then, Node.js. At first glance it sounds fantastic - you're working in JavaScript on the server side (so it's easy to learn, in theory) but there's no webserver. In other words, you write some JS that also functions *AS* the webserver.
From the Node.js docs, this would be pretty much the simplest possible webserver in Node:
Code: [Select]
Yup, you see that right. You're handling raw HTTP requests and headers. For someone like me who's been behind the cosy framework of PHP for years, this is... something of a change of pace. It's not a bad one at all, it's just a lot to take on board.
Especially with the heavy-going view it has towards I/O. In PHP, the script runs from top to bottom, and it waits for I/O to complete - so execution of a given page waits while a DB query completes, for example. This doesn't happen in Node, or at least it shouldn't.
The idea, really, is that you push the request off to another function and handle its response in a callback, so that mainline execution can get back to whatever it was doing. This, for me, is a *major* change of pace because it's just not a mentality I'm used to working in.
But, so far so good, actually. I was able to fashion something workable with that, but it wasn't really what I wanted, I wanted something that did some of the work for me. Yes, that's right, I started looking at frameworks and ended up with Express.
Express makes a lot of the work easier, but it has two problems. The first is that its documentation is absolutely crap. No, really, it's ABSOLUTELY SHIT. http://expressjs.com/guide.html is the entire official guide.
There's several sub-problems. Firstly, it makes no mention of Express 3.0 at all and only barely mentions 2.x in passing for migration. It would be OK reading the source, if Express were all the source, except it isn't. It's a framework on top of another framework, called Connect, and it's very hard to figure out WTF is going on when Express doesn't seem to point to another about Connect, like any other documentation.
The second problem is probably a bigger one in the scheme of things. A lot of people did figure out how to use Express and muddle through. And some people have written blogs on it, others have asked and answered things on StackOverflow. The result was that I've had dozens and dozens of tabs open in my browser for the last couple of days as I start to piece things together.
I mean, I have a functioning webserver, it receives requests, if they're dynamic pages, they're routed properly. If they're static resources, again routed properly. 404 and 500 have their own proper pages with correct headers and everything. But it took me over a day to figure all this out to make it work how I wanted because the documentation is so poor. And I mentioned that I had dozens and dozens of tabs open... I still have about 18 tabs open for the next stage of the project, and that's the problem in itself: there's so many bits and pieces on it but they're all haphazard and many of them are legacy items.
For example, I found one tutorial from late 2010 which refers to using Express methods for handling static content, and it refers to staticGzip and staticProvider; the former indicating that content should be gzipped and the latter to indicate that a given path is where static content should be served from.
But the manual doesn't mention these, it only talks about a method simply called static, which has a slightly different calling argument structure to staticProvider but does mostly the same job. After 20 minutes of digging around I found that staticProvider was deprecated in favour of simply static[1] and that staticGzip is no longer directly available because most people deploying such apps would serve static content like that from a CDN and not from your own server. A reasonable if slightly misguided idea, I think. As it happens in this case I'm looking at deploying with sufficiently long-life expiries that it doesn't really matter so much.
But anyway, I've spent so long trying to piece everything together that it's just left me feeling so frustrated.
I haven't actually told you the worst part yet, actually. Node has a nifty-in-principle tool called npm for installing packages. There's a central repository that lists packages and most of the time you can do npm install <package> and boom, it'll download. Unless it's Express, in which case you have to have make installed to be able to install it. This took me a while to figure out due to no-one describing it anywhere and npm giving me less than helpful messages.
It gets a bit better, actually. You can declare a package.json file which indicates a package's dependencies. This can be the Node versions supported, or it can be the version(s) of packages you need. My project needs Express, Socket.io and MongoDB's connector, seems straightforward enough. Until you hit the joys of figuring out which versions you need, of course.
Oh, and there's more fun. Each of those has other dependencies which also needs to be met. And it's not clear whether some of those come installed or as optional extras, Express for example states a 'devDependency' of Jade, though it doesn't actually install Jade unless you ask it to. Again, not documented anywhere. Then more version juggling.
Jade is actually pretty neat, though. Had we not had the template skeleton I might have suggested a move to it, because it allows for replacing blocks of a document, for prepending/appending content to blocks and so on. Plus the fact that Jade's syntax is incredibly tight and descriptive and not the usual verbosity of HTML itself. http://jade-lang.com/ if you're curious.
Anyway, that's enough rambling and venting from me. For my next challenge, figure out how sessions work (and figure out how to make them compliant with the EU laws, ahahahahah) and then bolt on Websockets type connections to it and maybe see if we can't do something truly wonderful from there on in!
The bottom line is that Node and its tools make for a very interesting and flexible platform for deploying unconventional applications but the lack of good documentation for major components (Node itself is well documented, just not its good bolt-ons so much) really makes it a struggle to implement anything.
I won't get into the detail of it but the last few days I've been snowed under - as I mentioned briefly - in building an app using Node.js, Express, Socket.io and MongoDB. I'm not going to explain what the app is, hopefully you'll see soon enough, but it's certainly been an interesting experience for me so far, and I feel like sharing what I've found.
First up, for those of who aren't familiar with Node.js, let me explain. We here are far more used to deploying apps where we have a web server like Apache, which receives requests, passes some of them onto PHP to process the contents of the page, and handles the page until it's ready and sends it back to the user.
It's convenient, practical and we're all used to it, but the app I've been working on lately requires longlife connections, what we would normally consider to be Comet style. I could have done it in AJAX but Comet is far less vicious on the server, especially given the real-time nature of the app in question, but in Apache/PHP this just is not practical.
Enter, then, Node.js. At first glance it sounds fantastic - you're working in JavaScript on the server side (so it's easy to learn, in theory) but there's no webserver. In other words, you write some JS that also functions *AS* the webserver.
From the Node.js docs, this would be pretty much the simplest possible webserver in Node:
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');Yup, you see that right. You're handling raw HTTP requests and headers. For someone like me who's been behind the cosy framework of PHP for years, this is... something of a change of pace. It's not a bad one at all, it's just a lot to take on board.
Especially with the heavy-going view it has towards I/O. In PHP, the script runs from top to bottom, and it waits for I/O to complete - so execution of a given page waits while a DB query completes, for example. This doesn't happen in Node, or at least it shouldn't.
The idea, really, is that you push the request off to another function and handle its response in a callback, so that mainline execution can get back to whatever it was doing. This, for me, is a *major* change of pace because it's just not a mentality I'm used to working in.
But, so far so good, actually. I was able to fashion something workable with that, but it wasn't really what I wanted, I wanted something that did some of the work for me. Yes, that's right, I started looking at frameworks and ended up with Express.
Express makes a lot of the work easier, but it has two problems. The first is that its documentation is absolutely crap. No, really, it's ABSOLUTELY SHIT. http://expressjs.com/guide.html is the entire official guide.
There's several sub-problems. Firstly, it makes no mention of Express 3.0 at all and only barely mentions 2.x in passing for migration. It would be OK reading the source, if Express were all the source, except it isn't. It's a framework on top of another framework, called Connect, and it's very hard to figure out WTF is going on when Express doesn't seem to point to another about Connect, like any other documentation.
The second problem is probably a bigger one in the scheme of things. A lot of people did figure out how to use Express and muddle through. And some people have written blogs on it, others have asked and answered things on StackOverflow. The result was that I've had dozens and dozens of tabs open in my browser for the last couple of days as I start to piece things together.
I mean, I have a functioning webserver, it receives requests, if they're dynamic pages, they're routed properly. If they're static resources, again routed properly. 404 and 500 have their own proper pages with correct headers and everything. But it took me over a day to figure all this out to make it work how I wanted because the documentation is so poor. And I mentioned that I had dozens and dozens of tabs open... I still have about 18 tabs open for the next stage of the project, and that's the problem in itself: there's so many bits and pieces on it but they're all haphazard and many of them are legacy items.
For example, I found one tutorial from late 2010 which refers to using Express methods for handling static content, and it refers to staticGzip and staticProvider; the former indicating that content should be gzipped and the latter to indicate that a given path is where static content should be served from.
But the manual doesn't mention these, it only talks about a method simply called static, which has a slightly different calling argument structure to staticProvider but does mostly the same job. After 20 minutes of digging around I found that staticProvider was deprecated in favour of simply static[1] and that staticGzip is no longer directly available because most people deploying such apps would serve static content like that from a CDN and not from your own server. A reasonable if slightly misguided idea, I think. As it happens in this case I'm looking at deploying with sufficiently long-life expiries that it doesn't really matter so much.
But anyway, I've spent so long trying to piece everything together that it's just left me feeling so frustrated.
I haven't actually told you the worst part yet, actually. Node has a nifty-in-principle tool called npm for installing packages. There's a central repository that lists packages and most of the time you can do npm install <package> and boom, it'll download. Unless it's Express, in which case you have to have make installed to be able to install it. This took me a while to figure out due to no-one describing it anywhere and npm giving me less than helpful messages.
It gets a bit better, actually. You can declare a package.json file which indicates a package's dependencies. This can be the Node versions supported, or it can be the version(s) of packages you need. My project needs Express, Socket.io and MongoDB's connector, seems straightforward enough. Until you hit the joys of figuring out which versions you need, of course.
Oh, and there's more fun. Each of those has other dependencies which also needs to be met. And it's not clear whether some of those come installed or as optional extras, Express for example states a 'devDependency' of Jade, though it doesn't actually install Jade unless you ask it to. Again, not documented anywhere. Then more version juggling.
Jade is actually pretty neat, though. Had we not had the template skeleton I might have suggested a move to it, because it allows for replacing blocks of a document, for prepending/appending content to blocks and so on. Plus the fact that Jade's syntax is incredibly tight and descriptive and not the usual verbosity of HTML itself. http://jade-lang.com/ if you're curious.
Anyway, that's enough rambling and venting from me. For my next challenge, figure out how sessions work (and figure out how to make them compliant with the EU laws, ahahahahah) and then bolt on Websockets type connections to it and maybe see if we can't do something truly wonderful from there on in!
The bottom line is that Node and its tools make for a very interesting and flexible platform for deploying unconventional applications but the lack of good documentation for major components (Node itself is well documented, just not its good bolt-ons so much) really makes it a struggle to implement anything.
| 1. | Including a snide mention from Express's author that JSLint is 'lame' because it can't differentiate between 'static' being used as a method name as being used to indicate something being static. |
162
Archived fixes / Drafts not collecting the topic properly
« on April 29th, 2012, 03:20 PM »
I have a draft post saved from a topic (though the fact the draft exists is a result of the QR/drafts bug), but the topic was since moved.
The code validates that it's still in the same board and same topic - but the topic doesn't exist in that board any more, even though it does certainly still exist.
It's not a huge deal except for the fact it doesn't link the title back to the topic and it says that editing it will cause it to open a new topic, even though it actually won't because it will tie it back to the topic properly.
The code validates that it's still in the same board and same topic - but the topic doesn't exist in that board any more, even though it does certainly still exist.
It's not a huge deal except for the fact it doesn't link the title back to the topic and it says that editing it will cause it to open a new topic, even though it actually won't because it will tie it back to the topic properly.
163
Archived fixes / Subjects with quotes in them are broken
« on April 27th, 2012, 05:24 PM »
I know it's been mentioned somewhere else but I wanted to discuss it here properly... eh, I did subsequently find it in the test board, http://wedge.org/pub/test/7303/test-topic/ where I mentioned the following:Quote Here's the problem: we don't re-encode it again in the display template. However, part of me thinks it would be better to re-encode it on saving and display the safe version at all times, rather than have potentially unsavoury content in the DB that could be used by plugin code that assumes it's safe like SMF does.
Thoughts?
Well, historically everything was done using htmlspecialchars with ENT_QUOTES so if it's not doing that now, there's a reason - and very likely that reason is code we've changed rather than code that's buggy in SMF.
Also note that the DB here isn't a true SMF database but one from Noisen's code which did have a lot of changes, and possibly including some that affected htmlspecialchars.
I'm fine with switching to ENT_NOQUOTES for such, provided that we can be certain there's no XSS injection risk. (There shouldn't be an SQL injection risk because of the query layer doing its own quoting.) It will certainly space some space (including the extra byte per row that I wanted to spend making it mediumtext ;))
Thoughts?
164
Features / Moving topics, you can now send a PM
« on April 25th, 2012, 11:56 PM »
I know it's been a bugbear of mine for a while that users weren't notified when their topics were moved.
Now they are, potentially.
And yes, as per my commit note in r1563, the message is a bit sucky but it makes the point well enough :)
Now they are, potentially.
Posted: April 25th, 2012, 11:55 PM
And yes, as per my commit note in r1563, the message is a bit sucky but it makes the point well enough :)
165
Archived fixes / custom.js detection throws errors
« on April 25th, 2012, 11:13 PM »file_get_contents(C:\wamp\www\wedge/Themes/default/scripts/custom.js) [<a href='function.file-get-contents'>function.file-get-contents</a>]: failed to open stream: No such file or directory